2010-12-17 27 views
23

Wie viele Elemente sind in einer Enum in Java maximal zulässig?Maximale Anzahl von Enum-Elementen in Java

Ich wollte die maximale Anzahl der Fälle in einer switch-Anweisung herausfinden. Da der größte in switch zulässige primitive Typ int ist, gibt es Fälle von -2.147.483.648 bis 2.147.483.647 und einen Standardfall. Jedoch sind Enums auch erlaubt ... so die Frage ..

+1

Wahrscheinlich weniger als 4 Milliarden. – Robert

+1

Ich habe keine Ahnung, aber würde gerne wissen, welche Art von Code denken Sie an, dass würde die maximale Größe eines Enum lol benötigen –

+1

Wenn ein s mit 2 Milliarden Fällen wechseln, werde ich wahrscheinlich jemanden töten, der hat habe diesen Code berührt. – Bozho

Antwort

25

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

Ich glaube, dass dies bedeutet, dass Sie nicht mehr als 65.535 Namen „Dinge“ in einer einzigen Klasse haben können, die auch die Anzahl der ENUM-Konstanten einschränken würden.

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

Zum Glück, das kann nicht geschehen:

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 ist kein Blocker - man kann den kompletten Schalter/2 Milliarden Fallblock in einer einzigen Zeile schreiben;) –

+6

@Andreas_D: es steht immer noch "65536 Bytes (Bytecode) pro Methode". Die Quellformatierung sollte dort keine Wirkung haben. – Thilo

+3

(mein Kommentar war nichts anderes als ein Witz) –

0

Es gibt keine maximale Anzahl per se für irgendwelche praktischen Zwecke. Wenn Sie Tausende von Enums in einer Klasse definieren müssen, müssen Sie Ihr Programm neu schreiben.

+4

gibt es eine maximale Anzahl für "praktische Zwecke". Das ist die Nummer, die funktioniert. Ich denke, der Punkt, den Sie versuchen zu machen, ist, dass es eine schlechte Übung/ein schlechter Stil ist, eine Aufzählung mit einer beliebigen Anzahl von Werten zu definieren. –

+1

LOL. Was für ein Argument. Als hätte man immer die Kontrolle über Datenstrukturen. In vielen, vielen Fällen werden sie extern vergeben und haben nichts mit Ihrem Code zu tun. Wenn es eine riesige Datenbank gibt, die sich im Laufe der Zeit entwickelt hat, und Sie eine Eigenschaft in Java abbilden möchten, um sie typsicher/kompilierbar-sicher oder was auch immer zu machen, ist das ziemlich vernünftig.Und Sie können nicht auf den DB-Betreuer/Admin/Entwickler zählen, um die internen Beschränkungen aller Sprachen zu berücksichtigen. – user1050755

2

Die Enum Klasse ein int verwendet Wert jeden Ordnungs zu verfolgen, so dass der max würde die gleiche wie int bestenfalls, wenn nicht viel niedriger.

Und wie schon andere gesagt haben, wenn man Sie fragen machst es falsch

3

Die maximale Größe jeder Methode in Java 65536 Bytes. Während Sie theoretisch einen großen Schalter oder mehrere Enum-Werte haben können, ist es die maximale Größe einer Methode, die Sie wahrscheinlich zuerst treffen werden.

7

Nun, auf jdk1.6 habe ich dieses Limit erreicht. Jemand hat 10.000 enum in einem xsd und wenn wir generieren, erhalten wir eine 60.000 Zeilenaufzählungs-Datei und ich bekomme einen netten Java-Compilerfehler von

[ERROR] konnte das Ziel nicht ausführen org.apache.maven.plugins: maven-compiler -plugin: 2.0.2: Kompilieren (Standard-kompilieren) im Projektrahmenwerk: Kompilierungsfehler [FEHLER]/Benutzer/dhiller/Leerzeichen/ifp-core/framework/target/generierte-sources/com/framework/util/LanguageCodeSimpleType. java: [7627,4] code zu groß

also ziemlich wahrscheinlich ist das Limit viel niedriger als die anderen Antworten hier ODER vielleicht die Kommentare und solche, die generiert werden, sind zu viel Platz einnehmen. Beachten Sie, dass die Zeilennummer in dem Java-Compiler-Fehler 7627 ist, aber wenn das Zeilenlimit 7627 ist, frage ich mich, was das Zeilenlängenlimit ist;) das ähnlich sein kann. dh. Die Grenzen können nicht auf der Anzahl der Aufzählungszeichen basieren, sondern auf Zeilenlängenbeschränkungen oder der Anzahl der Zeilen im Dateilimit, sodass Sie Umbenennung in A, B usw. sehr klein sein müssten, um mehr Enums in die Aufzählung aufzunehmen.

Ich kann nicht glauben, jemand schrieb eine Xsd mit einer 10.000 Enum .. Sie müssen diesen Teil der Xsd erzeugt haben.

6

Enums haben definitiv Grenzen, mit der primären (harten) Grenze um 32K Werte. Sie unterliegen Java-Klassen-Maxima, sowohl dem 'Konstanten-Pool' (64K Einträge) als auch - in einigen Compiler-Versionen - einem Methoden-Größenlimit (64K Bytecode) auf dem statischen Initialisierer.

'Enum' Initialisierung intern verwendet zwei Konstanten pro Wert - eine FieldRef und eine Utf8-Zeichenfolge. Dies ergibt die "harte Grenze" bei ~ 32K Werten.

Ältere Compiler (zumindest Eclipse Indigo) haben ebenfalls ein Problem hinsichtlich der Größe der statischen Initialisierungsmethode. Mit 24 Byte Bytecode, die erforderlich sind, um jeden Wert zu initialisieren, fügen Sie & dem Array Werte hinzu. eine Grenze um 2730 Werte kann auftreten.

Neuere Compiler (mindestens JDK 7) teilen große statische Initialisierer automatisch in die Methoden " enum constant initialization$2", " enum constant initialization$3" usw. auf, so dass sie nicht der zweiten Grenze unterliegen.

Sie können Bytecode über javap -v -c YourEnum.class demontieren, um zu sehen, wie dies funktioniert.

[Es könnte theoretisch möglich sein, eine "alte" Enum-Klasse als handcodiertes Java zu schreiben, um die Grenze von 32 K zu überschreiten und nahe 64K-Werten zu erreichen. Der Ansatz wäre, die Enum-Werte durch Reflektion zu initialisieren, um die Verwendung von String-Konstanten im Pool zu vermeiden. Ich testete diesen Ansatz und es funktioniert in Java 7, aber die Erwünschtheit eines solchen Ansatzes (Sicherheitsprobleme) ist fraglich.]

4

Die maximale Anzahl der Enum-Elemente ist 2746. Das Lesen der Spezifikation war sehr irreführend und verursachte mich zu erstellen ein fehlerhaftes Design mit der Annahme, dass ich niemals die 64K oder sogar 32K Hochwassermarke treffen würde. Leider ist die Anzahl viel niedriger als die Spezifikation zu zeigen scheint. Als Test habe ich Folgendes mit Java 7 und Java 8 versucht: Der folgende Code leitete den Code in eine Datei um und kompilierte die resultierende .java-Datei.

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+"}"); 

Ergebnis, 2746 funktioniert, und 2747 nicht.

Nach 2746 Einträge, der Compiler einen Code zu großen Fehler, wie

EnumSizeTest.java:2: error: code too large

Decompiling dieser Enum Klassendatei führt, wird die Einschränkung durch die für jeden ENUM-Wert im statischen Konstruktor erzeugten Code verursacht werden (meist).

+0

Es scheint, dass in der Sprachspezifikation etwas an dieser Grenze liegen sollte. Es kann nicht Sache des Compilers sein, zu entscheiden, wie viel es erlauben will. Welche Fehlermeldung haben Sie erhalten? – Thilo

+0

Ich habe den Beitrag bearbeitet, um deine Frage zu beantworten und meine Antwort zu erläutern. Ich hoffe, das hilft. – Derek

+0

Haben Sie ein 32-Bit- oder 64-Bit-JDK/JRE verwendet? – michaeak

Verwandte Themen