Frage

Angenommen, Sie eine hypothetische Enum in Java wie diese haben (rein zu Demonstrationszwecken, nicht-Code ist ich erwarte ernsthaft zu verwenden):

enum Example{
    FIRST,
    SECOND,
    THIRD,
    ...
    LAST;
}

Was ist die maximale Anzahl der Mitglieder ist man innerhalb dieser Enum haben könnte, bevor der Compiler Sie stoppt?

Zum anderen gibt es eine Performance-Unterschied zur Laufzeit, wenn Ihr Code eine ENUM verweist mit etwa 10 Mitgliedern als 100 oder 1000 (andere als nur die offensichtliche Speicheraufwand erforderlich, um die große Klasse speichern) entgegengesetzt?

War es hilfreich?

Lösung

Der beste Weg, die Antwort auf diese Art von Fragen, um herauszufinden, ist, es zu versuchen. Beginnen Sie mit einem kleinen Python-Skript der Java-Dateien zu generieren:

n = input()
print "class A{public static void main(String[] a){}enum B{"
print ','.join("C%d" % x for x in range(n))
print '}}'

Jetzt versuchen mit 1,10,100,1000 ... funktioniert gut, dann BAM:

A.java:2: Code zu groß C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14, C15, C16, C17, C18, C19, C20, C21, C22, ...

Es scheint, als ob ich eine Art interner Grenze erreicht. Nicht sicher, ob es ein dokumentierte Limit ist, wenn es auf der spezifischen Version meines Compiler, oder wenn sie einige systemabhängige Grenze abhängig ist. Aber für mich war die Grenze um 3000 und erscheint auf den Quellcode Größe bezogen werden. Vielleicht könnten Sie Ihren eigenen Compiler schreiben, diese Grenze zu umgehen.

Andere Tipps

Die Sprachspezifikation selbst hat keine Grenze. Dennoch gibt es viele Einschränkungen, die Klassendatei hat, dass die Anzahl von Aufzählungen gebunden, wobei die obere Grenze 65.536 aruond wobei (2 ^ 16) enums:

Die Anzahl der Felder Die JVMs 4.1 gibt an, dass ClassFile kann bis zu 65.536 (2 ^ 16) Feldern. Aufzählungen in der Klassendatei als statisches Feld gespeichert zu bekommen, so dass die maximale Anzahl der ENUM-Werte und Enum Mitgliederfelder ist 65.536.

Constant Pool Die JVMs gibt auch, dass der Constant Pool bis zu 65.536 hat. Constant Pools speichern alle Stringliterale, Typ Literale, geordneter Typ, super-Schnittstellen-Typen, Methodensignaturen, Methodennamen, und ENUM-Wert Namen. So muss es sein, weniger als 2 ^ 16 ENUM-Werte, da die Namen Zeichenfolgen, die Constant Pool Grenze teilen müssen.

Statische Methode Initialisierung Die Höchstgrenze für ein Verfahren ist 65.535 Bytes (in Bytecode). So ist die statischen Initialisierer für die Enum muss kleiner sein als 64 KB. Während der Compiler es in verschiedene Methoden aufteilen (Blick auf Bug-ID: 4262078 ) die Initialisierungen in kleine Blöcke zu verteilen, wird der Compiler nicht, dass zur Zeit.

Lange Rede kurzer Sinn, gibt es keine einfache Antwort, und die Antwort hängt nicht nur von der Anzahl der ENUM-Werte sind, sondern auch die Anzahl der Methoden, Schnittstellen und Felder der Aufzählungen haben!

Die maximale Anzahl des ENUM-Wertes werden denken, ich nur unter der 65536 maximalen Anzahl von Feldern / Konstanten-Pool-Einträgen in der Klasse sein. (Wie ich in einem Kommentar oben erwähnt, können die tatsächlichen Werte sollten nicht konstant Pool-Einträge übernehmen. Sie können „inline“ in den Bytecode, aber die Namen werden)

Was die zweite Frage betrifft, so gibt es keinen direkten Performance-Unterschied ist, aber es ist denkbar, dass es klein sein werde indirekte Leistungsunterschiede, zum Teil wegen der Klasse Dateigröße, wie Sie sagen. Eine andere Sache im Auge zu behalten ist, dass wenn Sie auf Enum Sammlungen gibt es Versionen von einigen der Klassen optimiert werden, wenn alle der ENUM-Werte passen innerhalb eines bestimmten Bereichs (ein Byte, wie ich mich erinnere) . Also ja, es könnte ein kleiner Unterschied sein. Ich woudln't paranoid, aber.

Dies ist eine Erweiterung der Kommentare auf die ursprüngliche Frage.

Es gibt mehrere Probleme mit einer Menge von Aufzählungen mit.

Der Hauptgrund dafür ist, dass, wenn Sie eine Menge Daten haben, es zu ändern neigt, oder wenn nicht möchten, dass Sie oft neue Elemente hinzuzufügen. Es gibt Ausnahmen von dieser wie die Umrechnung von Einheiten, die sich nie ändern würde, aber zum größten Teil wollen Sie Daten wie diese aus einer Datei in eine Sammlung von Klassen zu lesen und nicht als ENUM.

neue Einträge hinzuzufügen ist problematisch, weil, da es eine Enumeration ist, müssen Sie körperlich Ihren Code ändern, wenn Sie immer die Aufzählungen als eine Sammlung verwenden, und wenn Sie immer benutzen sie als eine Sammlung, warum überhaupt diese Aufzählungen machen ?

Der Fall, dass Ihre Daten nicht ändern - wie „Umwandlungseinheiten“, wo Sie die Füße konvertieren, Zoll, etc. Sie tun könnten dies als Aufzählungen und es gäbe eine Menge von ihnen, aber von ihnen als Aufzählungen Codierung Sie verlieren die Fähigkeit, Daten Ihr Programm fahren zu lassen. Zum Beispiel kann ein Benutzer aus einer Pull-Down-Liste von Ihrer „Einheit“ bevölkerte wählen könnte, aber auch dies ist kein „ENUM“ usage, dann ist es es als eine Sammlung verwenden.

Das andere Problem wird um die Verweise auf Ihre Enum Wiederholung werden. Sie werden mit ziemlicher Sicherheit etwas sehr repetitiv haben wie:

if(userSelectedCard() == cards.HEARTS)
    graphic=loadFile("Heart.jpg");
if(userSelectedCard() == cards.SPADES)
    graphic=loadFile("Spade.jpg");

Welche einfach falsch ist (Wenn Sie schielen können, wo Sie die Buchstaben nicht lesen kann und diese Art von Muster in Ihrem Code sehen, Sie wissen, dass es falsch machen).

Wenn die Karten in einer Kartensammlung gespeichert wurden, wäre es einfacher, nur zu verwenden:

graphic=cards.getGraphicFor(userSelectedCard());

Ich sage nicht, dass dies nicht auch mit einem Enum getan werden, aber ich sage, dass ich nicht sehen kann, wie Sie diese als Aufzählungen ohne einig bösen Code-Block wie das verwenden würden ich gepostet oben.

ich auch nicht sagen, dass es keine Fälle für Aufzählungen - es gibt viele von ihnen, aber wenn man mehr als ein paar bekommen (7 war eine gute Zahl), sind Sie wahrscheinlich besser dran mit einem anderen Struktur.

ich denke, die Ausnahme ist, wenn Sie reale Sachen modellieren, die, dass viele Arten haben und jeder muss mit unterschiedlichem Code angesprochen werden, aber selbst dann sind Sie wahrscheinlich besser dran, eine Datendatei mit einem Namen zu einigem Code zu binden laufen und sie in einem Hash zu speichern, damit Sie sie kann wie mit dem Code aufrufen: hash.get (Namestring) .executeCode (). Auf diese Weise wieder, Ihr „Namestring“ Daten und nicht hartcodiert, so dass Refactoring an anderer Stelle.

Wenn Sie die Gewohnheit brutal Factoring Ihren Code wie diese zu erhalten, können Sie viele Programme um 50% oder mehr in der Größe reduzieren.

Wenn Sie fragen haben, sind Sie wahrscheinlich etwas falsch zu machen. Die tatsächliche Grenze wahrscheinlich ziemlich hoch ist, aber eine Enumeration mit mehr als 10 oder so Werten würde höchst verdächtig sein, denke ich. Brechen, dass bis in verwandten Sammlungen oder eine Art Hierarchie, oder so etwas.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top