gpt4 book ai didi

Java 枚举和其他类文件

转载 作者:行者123 更新时间:2023-12-03 20:46:44 25 4
gpt4 key购买 nike

我注意到 enums编译后引入许多额外的类文件 (Class$1) 使总大小膨胀。它似乎附加到每个甚至使用枚举的类,并且这些经常重复。

为什么会发生这种情况,有没有办法在不删除枚举的情况下防止这种情况发生。

(问题的原因是空间对我来说非常宝贵)

编辑

在进一步调查此问题时,Sun 的 每次在 Enum 上使用开关时,Javac 1.6 都会创建一个额外的合成类 .它使用某种 SwitchMap。 This网站有更多信息,和here告诉您如何分析 Javac 正在做什么。

每次在枚举上使用开关时,额外的物理文件似乎都需要付出高昂的代价!

有趣的是,Eclipe 的编译器不会生成这些附加文件。我想知道是否唯一的解决方案是切换编译器?

最佳答案

我只是被这种行为所困扰,并且在谷歌搜索时出现了这个问题。我想我会分享一些我发现的额外信息。

每次在枚举上使用开关时,javac 1.5 和 1.6 都会创建一个额外的合成类。该类包含一个所谓的“切换映射”,它将枚举索引映射到切换表跳转编号。重要的是,合成类是为发生切换的类创建的,而不是为枚举类创建的。

以下是生成内容的示例:

枚举类

public enum EnumClass { VALUE1, VALUE2, VALUE3 }

枚举用户
public class EnumUser {
public String getName(EnumClass value) {
switch (value) {
case VALUE1: return "value 1";
// No VALUE2 case.
case VALUE3: return "value 3";
default: return "other";
}
}
}

合成 EnumUser$1.class
class EnumUser$1 {
static final int[] $SwitchMap$EnumClass = new int[EnumClass.values().length];

static {
$SwitchMap$EnumClass[EnumClass.VALUE1.ordinal()] = 1;
$SwitchMap$EnumClass[EnumClass.VALUE3.ordinal()] = 2;
};
}

然后使用此开关映射为 lookupswitch 生成索引。或 tableswitch JVM 指令。它将每个枚举值转换为从 1 到 [开关案例数] 的相应索引。

枚举用户类
public java.lang.String getName(EnumClass);
Code:
0: getstatic #2; //Field EnumUser$1.$SwitchMap$EnumClass:[I
3: aload_1
4: invokevirtual #3; //Method EnumClass.ordinal:()I
7: iaload
8: lookupswitch{ //2
1: 36;
2: 39;
default: 42 }
36: ldc #4; //String value 1
38: areturn
39: ldc #5; //String value 3
41: areturn
42: ldc #6; //String other
44: areturn
tableswitch如果存在三个或更多开关情况,则使用它,因为与 lookupswitch 相比,它执行更有效的恒定时间查找。的线性搜索。从技术上讲,当 javac 使用 lookupswitch 时,javac 可以使用合成开关映射省略整个业务。 .

推测:我手头没有 Eclipse 的编译器来测试,但我想它不会打扰合成类,只是使用 lookupswitch .或者它可能需要比原始提问者在“升级”到 tableswitch 之前测试的更多开关盒。 .

关于Java 枚举和其他类文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65196529/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com