Maximum number of enum elements in Java

What is the maximum number of elements allowed in an enum in 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..


Solution 1:

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.

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.

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

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).

Solution 2:

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.

    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.

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

EnumSizeTest.java:2: error: code too large

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

Solution 3:

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.

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

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.

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.

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

[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 reflection to 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.]

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

Solution 4:

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

[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

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.

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