Java中的最大枚举元素数

Java中枚举允许的最大元素数是多少?

我想找出switch语句中的最大个案数。 由于switch中允许的最大基本类型是int,因此我们有-2,147,483,648到2,147,483,647的情况和一个默认情况。 但是也允许枚举…所以问题..

从类文件格式规范 :

ClassFile结构的16位constant_pool_count字段(第4.1节)将每类或每接口常量池限制为65535个条目。 这是对单个类或接口的总复杂性的内部限制。

我相信这意味着你不能在单个类中拥有超过65535个命名的“东西”,这也会限制枚举常量的数量。

如果看到一个有20亿个案例的交换机,我可能会杀死触及该代码的任何人。

幸运的是,这不可能发生:

每个非本机非抽象方法的代码量由Code属性(第4.7.3节)的exception_table中的索引大小限制为65536字节,在LineNumberTable属性(第4.7.8节)中,在LocalVariableTable属性中(§4.7.9)。

枚举元素的最大数量是2746.阅读规范是非常误导的,并且让我创造了一个有缺陷的设计,假设我永远不会达到64K甚至32K的高水位。 不幸的是,这个数字远低于规格似乎表明的数字。 作为测试,我尝试了以下Java 7和Java 8:将以下代码重定向到一个文件,然后编译生成的.java文件。

System.out.println("public enum EnumSizeTest {"); int max = 2746; for ( int i=0; i 

结果,2746个工作,2747没有。

在2746个条目之后,编译器会抛出一个代码太大的错误,就像

EnumSizeTest.java:2:错误:代码太大了

反编译此Enum类文件时,限制似乎是由为静态构造函数(主要)中的每个枚举值生成的代码引起的。

好吧,在jdk1.6上我达到了这个极限。 有人在xsd中有10,000个枚举,当我们生成时,我们得到一个60,000行枚举文件,我得到一个很好的java编译器错误

[错误]无法执行目标org.apache.maven.plugins:maven-compiler-plugin:2.0.2:项目框架上的编译(default-compile):编译失败[ERROR] / Users / dhiller / Space / ifp-core /framework/target/generated-sources/com/framework/util/LanguageCodeSimpleType.java:[7627,4]代码太大

所以很可能这个限制比这里的其他答案要低很多,或者可能产生的评论等产生了太大的空间。 注意java编译器错误中的行号是7627,但是如果行限制是7627,我想知道行长度限制是什么;)这可能是类似的。 即。 限制可能不是基于枚举的数量,而是基于行长度限制或文件限制中的行数,因此您可以将枚举重命名为A,B等,以使更多的枚举适合枚举。

我不敢相信有人写了一个带有10,000枚枚举的xsd ……他们必须已经生成了xsd的这一部分。

枚举肯定有限制,主要(硬)限制大约32K值。 它们受Java类最大值的限制,包括“常量池”(64K条目)和 – 在某些编译器版本中 – 对静态初始化程序的方法大小限制(64K字节码)。

内部’枚举’初始化,每个值使用两个常量 – FieldRef和Utf8字符串。 这给出了~32K值的“硬限制”。

较旧的编译器(至少Eclipse Indigo)也遇到了静态初始化方法大小的问题。 使用24字节的字节码来实例化每个值并将其添加到values数组中。 可能遇到约2730个值的限制。

较新的编译器(至少JDK 7)自动将大型静态初始化器拆分为名为" enum constant initialization$2"" enum constant initialization$3"等的方法,因此不受第二个限制的约束。

您可以通过javap -v -c YourEnum.class反汇编字节码,看看它是如何工作的。

[理论上可以将“旧式”Enum类编写为手动编码的Java,以打破32K限制并接近64K值。 方法是通过reflection初始化枚举值,以避免在池中需要字符串常量。 我测试了这种方法,它在Java 7中运行,但这种方法(安全问题)的可取性值得怀疑。

编者注:Utf8是Java类文件IIRC中的内部类型,它不是一个错误的纠正。

Java中任何方法的最大大小为65536字节。 虽然理论上你可以有一个大的开关或更多的枚举值,但它是你可能首先遇到的方法的最大大小。

Enum类使用int来跟踪每个值的序数,因此最大值最好与int相同,如果不低得多的话。

正如其他人所说,如果你不得不问你做错了

任何实际用途都没有最大数量。 如果您需要在一个类中定义数千个枚举,则需要重写您的程序。