gpt4 book ai didi

Java 枚举和其他类文件

转载 作者:搜寻专家 更新时间:2023-10-30 23:02:16 24 4
gpt4 key购买 nike

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

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

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

编辑

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

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

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

最佳答案

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

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

这是生成内容的示例:

枚举类.java

public enum EnumClass { VALUE1, VALUE2, VALUE3 }

枚举用户.java

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;
};
}

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

枚举用户类

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 在存在三个或更多 switch 情况时使用,因为与 lookupswitch 的线性搜索相比,它执行更高效的恒定时间查找。从技术上讲,当 javac 使用 lookupswitch 时,它可以通过合成开关映射省略整个业务。

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

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

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