在java枚举中你可以拥有的成员数限制是多少?

mpo*_*ien 6 java compiler-construction performance enums runtime

假设你在这样的java中有一个假设的枚举(纯粹用于演示目的,这不是我非常期待使用的代码):

enum Example{
    FIRST,
    SECOND,
    THIRD,
    ...
    LAST;
}
Run Code Online (Sandbox Code Playgroud)

在编译器停止之前,你可以在枚举中拥有的最大成员数是多少?

其次,当您的代码引用枚举时,运行时是否有任何性能差异,例如10个成员而不是100或1,000(除了存储大型类所需的明显内存开销)?

not*_*oop 14

语言规范本身没有限制.然而,classfile有许多限制枚举的数量,上限为aruond 65,536(2 ^ 16)枚举:

场的数目JVMS 4.1指定对ClassFile可能有多达65536(2 ^ 16)字段.枚举作为静态字段存储在类文件中,因此枚举值和枚举成员字段的最大数量为65,536.

常量池 JVMS还指定常量池最多可以有65,536.常量池存储所有字符串文字,类型文字,超类型,超级接口类型,方法签名,方法名称和AND枚举值名称.因此,必须少于2 ^ 16个枚举值,因为名称字符串需要共享该常量池限制.

静态方法初始化方法 的最大限制为65,535字节(以字节码为单位).因此Enum的静态初始化程序必须小于64Kb.虽然编译器可能将其拆分为不同的方法(查看错误ID:4262078)以将初始化分发为小块,但编译器当前不会这样做.

简而言之,没有简单的答案,答案不仅取决于枚举值的数量,还取决于枚举的方法,接口和字段的数量!


Mar*_*ers 10

找出这类问题答案的最佳方法是尝试一下.从一个小的Python脚本开始生成Java文件:

n = input()
print "class A{public static void main(String[] a){}enum B{"
print ','.join("C%d" % x for x in range(n))
print '}}'
Run Code Online (Sandbox Code Playgroud)

现在试试1,10,100,1000 ...工作正常,然后BAM:

A.java:2:代码太大C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16,C17,C18,C19,C20 ,C21,C22,...

好像我达到某种内部限制.不确定它是否是文档限制,如果它取决于我的编译器的特定版本,或者它是否依赖于系统限制.但对我来说,限制大约是3000,并且似乎与源代码大小有关.也许你可以编写自己的编译器来绕过这个限制.

  • 我可能并不完全认真. (9认同)
  • Java 中单个方法的长度限制为 64K 字节。这是一个 JVM 问题,但由于有解决方法,在这种情况下它是一个编译器问题。我的猜测是 2747 个枚举导致长度约为 64K 的初始化方法。 (2认同)