2010-12-17 38 views
23

¿Cuál es la cantidad máxima de elementos permitidos en una enumeración en Java?Número máximo de elementos enum en Java

Quería conocer el número máximo de casos en una declaración de cambio. Como el tipo primitivo más grande permitido en el interruptor es int, tenemos casos desde -2,147,483,648 hasta 2,147,483,647 y un caso por defecto. Sin embargo, las enumeraciones también están permitidas ... entonces la pregunta ...

+1

Probablemente menos de 4 mil millones. – Robert

+1

No tengo ni idea, pero me gustaría saber qué tipo de código estás pensando que requeriría saber el tamaño máximo de una enumeración lol –

+1

Si veo un cambio con 2 mil millones de casos, probablemente mate a cualquiera que tenga tocó ese código. – Bozho

Respuesta

25

Desde el 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.

creo que esto implica que no se puede tener más de 65.535 llamados "cosas" en una sola clase, que también limitaría el número de constantes de enumeración.

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

Afortunadamente, eso no puede suceder:

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

+5

LineNumberTable no es un bloqueador; se puede escribir el interruptor completo/2 mil millones de bloque de caso en una sola línea;) –

+6

@Andreas_D: todavía dice "65536 bytes (de código de bytes) por método". El formato de la fuente no debería tener ningún efecto allí. – Thilo

+3

(mi comentario no fue más que una broma) –

0

No hay número máximo per se para ningún propósito práctico. Si necesita definir miles de enumeraciones en una clase, necesita volver a escribir su programa.

+4

hay un número máximo para "fines prácticos". Ese es el número que funciona. Creo que el punto que intentas hacer es que es una mala práctica/un estilo malo definir una enumeración con cualquier cantidad cercana a esa cantidad de valores. –

+1

LOL. Qué argumento. Como si uno siempre tuviera control sobre las estructuras de datos. En muchos casos, muchos se dan de forma externa y no tienen nada que ver con su código. Si hay una enorme base de datos que se ha desarrollado con el tiempo, y desea mapear una propiedad en java para que sea segura para tipos/segura para compilación o lo que sea, eso es algo bastante razonable de hacer.Y no puede contar con el desarrollador/administrador/desarrollador de DB para tener en cuenta las limitaciones internas de todos los idiomas. – user1050755

2

La clase Enum utiliza un int para rastrear ordinal de cada valor, por lo que el máximo sería el mismo que el int a lo mejor, si no es mucho menor.

y como otros han dicho, si tiene que pedir que lo está haciendo incorrecto

3

El tamaño máximo de cualquier método en Java es 65536 bytes. Si bien teóricamente puedes tener un interruptor grande o más valores enum, es el tamaño máximo de un método que es probable que golpees primero.

7

Bueno, en jdk1.6 llegué a este límite. Alguien tiene 10.000 enum en una xsd y cuando generamos, obtenemos un archivo enum de 60,000 líneas y obtengo un buen error de compilación java de

[ERROR] Error al ejecutar la meta org.apache.maven.plugins: maven-compiler -plugin: 2.0.2: compilar (compilación predeterminada) en el marco del proyecto: Error de compilación [ERROR]/Users/dhiller/Space/ifp-core/framework/target/generated-sources/com/framework/util/LanguageCodeSimpleType. java: [7627,4] código demasiado grande

así que posiblemente el límite sea mucho más bajo que las otras respuestas aquí O tal vez los comentarios y los que se generan están ocupando demasiado espacio. Observe que el número de línea es 7627 en el error del compilador de Java, aunque si el límite de la línea es 7627, me pregunto cuál es el límite de longitud de línea;) que puede ser similar. es decir. los límites no se pueden basar en el número de enumeraciones, sino en los límites de longitud de línea o en el límite de archivos, por lo que habría cambiado el nombre de las enumeraciones por A, B, etc., para que sean más pequeñas y que entren más enumeraciones en la enumeración.

No puedo creer que alguien haya escrito una xsd con una enumeración de 10.000 ... deben haber generado esta parte de la xsd.

6

Las enumeraciones definitivamente tienen límites, sin el límite primario (difícil) alrededor de 32K. Están sujetos a los máximos de clase Java, tanto del "grupo constante" (entradas 64K) como, en algunas versiones del compilador, al límite de tamaño del método (código de bytes 64K) en el inicializador estático.

Inicialización 'Enum' internamente, utiliza dos constantes por valor: una cadena FieldRef y una cadena Utf8. Esto da el "límite duro" en ~ 32K valores.

Los compiladores antiguos (al menos Eclipse Indigo) también tienen un problema con el tamaño del método del inicializador estático. Con 24 bytes de bytecode necesarios para crear una instancia de cada valor &, agréguelo a la matriz de valores. se puede encontrar un límite de alrededor de 2730 valores.

Los compiladores más nuevos (al menos JDK 7) dividen automáticamente inicializadores estáticos grandes en los métodos denominados " enum constant initialization$2", " enum constant initialization$3" etc. por lo que no están sujetos al segundo límite.

Puede desmontar bytecode a través del javap -v -c YourEnum.class para ver cómo funciona esto.

[Podría ser teóricamente posible escribir una clase Enum "antigua" como una codificación manual de Java, para romper el límite de 32K y acercarse a valores de 64K. El enfoque sería inicializar los valores enum por reflexión para evitar la necesidad de contar con constantes de cadena en el conjunto. Probé este enfoque y funciona en Java 7, pero la conveniencia de tal enfoque (problemas de seguridad) es cuestionable.]

4

El número máximo de elementos enum es 2746. Leer la especificación fue muy engañoso y me llevó a crear un diseño defectuoso con la suposición de que nunca alcanzaría la marca de 64K o 32K de altura. Lamentablemente, el número es mucho más bajo de lo que parece indicar la especificación. Como prueba, intenté lo siguiente con Java 7 y Java 8: ejecuté el siguiente código redirigiéndolo a un archivo, luego compilé el archivo resultante .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+"}"); 

Resultado, 2746 obras y 2747 no.

Después de 2746 entradas, el compilador lanza un código demasiado grande error, como

EnumSizeTest.java:2: error: code too large

Descompilación este archivo de clase de enumeración, la restricción parece ser causado por el código generado para cada valor de enumeración en el constructor estático (principalmente).

+0

Parece que debe haber algo sobre ese límite en la especificación del idioma. No puede depender del compilador decidir cuánto quiere permitir. ¿Qué mensaje de error obtuviste? – Thilo

+0

Edité la publicación para responder a su pregunta y explicar mejor mi respuesta. Espero que ayude. – Derek

+0

¿Utilizaste un JDK/JRE de 32 o 64 bits? – michaeak