Java 中枚举元素的最大数量

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4468388/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 06:31:32  来源:igfitidea点击:

Maximum number of enum elements in Java

javaenumsswitch-statement

提问by Rnet

What is the maximum number of elements allowed in an enum in Java?

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

I wanted to find out the maximum number of cases in a switch statement. Since the largest primitive type allowed in switch is int, we have cases from -2,147,483,648 to 2,147,483,647 and one default case. However enums are also allowed... so the question..

我想找出 switch 语句中的最大案例数。由于 switch 中允许的最大原始类型是 int,我们有从 -2,147,483,648 到 2,147,483,647 的情况和一种默认情况。然而,枚举也是允许的......所以问题......

回答by Thilo

From the class file format spec:

类文件格式规范

The per-class or per-interface constant pool is limited to 65535 entries by the 16-bit constant_pool_count field of the ClassFile structure (§4.1). This acts as an internal limit on the total complexity of a single class or interface.

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

I believe that this implies that you cannot have more then 65535 named "things" in a single class, which would also limit the number of enum constants.

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

If a see a switch with 2 billion cases, I'll probably kill anyone that has touched that code.

如果看到一个包含 20 亿个案例的开关,我可能会杀死任何接触过该代码的人。

Fortunately, that cannot happen:

幸运的是,这不会发生:

The amount of code per non-native, non-abstract method is limited to 65536 bytes by the sizes of the indices in the exception_table of the Code attribute (§4.7.3), in the LineNumberTable attribute (§4.7.8), and in the LocalVariableTable attribute (§4.7.9).

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

回答by Derek

The maximum number of enum elements is 2746. Reading the spec was very misleading and caused me to create a flawed design with the assumption I would never hit the 64K or even 32K high-water mark. Unfortunately, the number is much lower than the spec seems to indicate. As a test, I tried the following with both Java 7 and Java 8: Ran the following code redirecting it to a file, then compiled the resulting .java file.

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

    System.out.println("public enum EnumSizeTest {");
    int max = 2746;
    for ( int i=0; i<max; i++) {
        System.out.println("VAR"+i+",");
    }
    System.out.println("VAR"+max+"}");

Result, 2746 works, and 2747 does not.

结果,2746 有效,2747 无效。

After 2746 entries, the compiler throws a code too large error, like

2746个条目后,编译器抛出code too large错误,比如

EnumSizeTest.java:2: error: code too large

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

Decompiling this Enum class file, the restriction appears to be caused by the code generated for each enum value in the static constructor (mostly).

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

回答by Dean Hiller

Well, on jdk1.6 I hit this limit. Someone has 10,000 enum in an xsd and when we generate, we get a 60,000 line enum file and I get a nice java compiler error of

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

[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:2.0.2:compile (default-compile) on project framework: Compilation failure [ERROR] /Users/dhiller/Space/ifp-core/framework/target/generated-sources/com/framework/util/LanguageCodeSimpleType.java:[7627,4] code too large

[错误] 无法执行目标 org.apache.maven.plugins:maven-compiler-plugin:2.0.2:compile (default-compile) on project framework: Compilation failure [ERROR] /Users/dhiller/Space/ifp-core /framework/target/generated-sources/com/framework/util/LanguageCodeSimpleType.java:[7627,4] 代码太大

so quite possibly the limit is much lower than the other answers here OR maybe the comments and such that are generated are taking up too much space. Notice the line number is 7627 in the java compiler error though if the line limit is 7627, I wonder what the line length limit is ;) which may be similar. ie. the limits may be not be based on number of enums but line length limits or number of lines in the file limit so you would have rename enums to A, B, etc. to be very small to fit more enums into the enum.

所以很可能这个限制比这里的其他答案低得多,或者生成的评论等占用了太多空间。请注意,java 编译器错误中的行号是 7627,但如果行限制是 7627,我想知道行长度限制是多少;) 这可能是相似的。IE。限制可能不是基于枚举数,而是基于行长度限制或文件限制中的行数,因此您可以将枚举重命名为 A、B 等,使其非常小,以便将更多枚举放入枚举中。

I can't believe someone wrote an xsd with a 10,000 enum..they must have generated this portion of the xsd.

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

回答by Thomas W

Enums definitely have limits, with the primary (hard) limit around 32K values. They are subject to Java class maximums, both of the 'constant pool' (64K entries) and -- in some compiler versions -- to a method size limit (64K bytecode) on the static initializer.

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

'Enum' initialization internally, uses two constants per value -- a FieldRef and a Utf8 string. This gives the "hard limit" at ~32K values.

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

Older compilers (Eclipse Indigo at least) also run into an issue as to the static initializer method-size. With 24 bytes of bytecode required to instantiate each value & add it to the values array. a limit around 2730 values may be encountered.

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

Newer compilers (JDK 7 at least) automatically split large static initializers off into methods named " enum constant initialization$2", " enum constant initialization$3"etc so are not subject to the second limit.

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

You can disassemble bytecode via javap -v -c YourEnum.classto see how this works.

您可以通过反汇编字节码javap -v -c YourEnum.class来查看其工作原理。

[It might be theoretically possible to write an "old-style" Enum class as handcoded Java, to break the 32K limit and approach close to 64K values. The approach would be to initialize the enum values by reflectionto avoid needing string constants in the pool. I tested this approach and it works in Java 7, but the desirability of such an approach (safety issues) are questionable.]

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

Note to editors: Utf8 was an internal type in the Java classfile IIRC, it's not a typo to be corrected.

编辑注意:Utf8 是 Java 类文件 IIRC 中的内部类型,它不是一个需要更正的错字。

回答by Peter Lawrey

The maximum size of any method in Java is 65536 bytes. While you can theoretically have a large switch or more enum values, its the maximum size of a method you are likely to hit first.

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

回答by Brad Mace

The Enumclass uses an intto track each value's ordinal, so the max would be the same as int at best, if not much lower.

Enum类使用int跟踪每个值的序数,因此最大将是相同充其量INT,如果不是要低得多。

And as others have said, if you have to ask you're Doing It Wrong

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

回答by fastcodejava

There is no maximum number per sefor any practical purposes. If you need to define thousands of enums in one class you need to rewrite your program.

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