2010-12-17 15 views
23

Jaka jest maksymalna liczba elementów dozwolonych w wyliczeniu w języku Java?Maksymalna liczba elementów wyliczających w języku Java

Chciałem dowiedzieć się o maksymalnej liczbie przypadków w instrukcji switch. Ponieważ największym typem pierwotnym dozwolonym w przełączniku jest int, mamy przypadki od -2,147,483,648 do 2 147 483 647 i jeden domyślny przypadek. Jednak wyliczenia są również dozwolone ... więc pytanie ..

+1

Prawdopodobnie mniej niż 4 miliardy. – Robert

+1

Nie mam pojęcia, ale chciałbym wiedzieć, jaki typ kodu myślisz o tym, że musisz znać maksymalny rozmiar enum lol –

+1

Jeśli widzę przełącznik z 2 miliardami przypadków, prawdopodobnie zabiję każdego, kto ma dotknął tego kodu. – Bozho

Odpowiedz

25

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

wierzę, że oznacza to, że nie można mieć więcej niż 65535 o nazwie „rzeczy” w jednej klasie, które również ograniczają liczbę stałych enum.

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

szczęście, że nie może się zdarzyć:

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 nie jest blokerem - można zapisać pełny przełącznik/2 miliardy bloków obudowy w jednym wierszu;) –

+6

@Andreas_D: wciąż mówi "65536 bajtów (kodu bajtowego) dla każdej metody". Formatowanie źródłowe nie powinno tam mieć żadnego wpływu. – Thilo

+3

(mój komentarz był tylko żartem) –

0

Nie ma maksymalnej liczby per se dla celów praktycznych. Jeśli chcesz zdefiniować tysiące wyliczeń w jednej klasie, powinieneś przepisać swój program.

+4

istnieje maksymalna liczba dla "celów praktycznych". To jest liczba, która działa. Myślę, że punktem, który próbujesz zrobić, jest to, że jest to zły styl/zły styl definiowania wyliczenia z dowolną wartością zbliżoną do wartości. –

+1

LOL. Co za kłótnia. Tak jakby zawsze miał kontrolę nad strukturami danych. W wielu przypadkach są one podawane zewnętrznie i nie mają nic wspólnego z kodem. Jeśli istnieje ogromna baza danych, która rozwinęła się w czasie i chcesz zmapować własność na język Java, aby była bezpieczna pod względem typu/kompilacji lub cokolwiek innego, jest to całkiem rozsądna sprawa.I nie możesz liczyć na to, że opiekun DB/administrator/programista bierze pod uwagę wewnętrzne ograniczenia wszystkich języków. – user1050755

2

Klasa Enum wykorzystuje int śledzić porządkowa każdej wartości, więc max byłyby takie same jak int w najlepszym razie, jeśli nie znacznie niższa.

I jak mówili inni, jeśli trzeba zadać robisz to źle

3

Maksymalny rozmiar każdej metody w Javie jest 65536 bajtów. Chociaż teoretycznie możesz mieć duży przełącznik lub więcej wartości wyliczeniowych, jest to maksymalny rozmiar metody, którą prawdopodobnie uderzysz jako pierwszy.

7

Cóż, na jdk1.6 trafiłem w ten limit. Ktoś ma 10 000 enum w xsd i kiedy generujemy, dostajemy 60 000 liniowych plików enum i dostaję ładnego błędu kompilatora Javy

[ERROR] Nie udało się wykonać celu org.apache.maven.plugins: maven-compiler -plugin: 2.0.2: kompilacja (kompilacja domyślna) w środowisku projektu: Awaria kompilacji [ERROR]/Users/dhiller/Space/ifp-core/framework/target/generated-sources/com/framework/util/LanguageCodeSimpleType. java: [7627,4] kod zbyt duży

więc całkiem możliwe, że limit jest znacznie niższy niż inne odpowiedzi tutaj. Może komentarze i takie, które są generowane, zabierają zbyt dużo miejsca. Zauważ, że numer wiersza to 7627 w błędzie kompilatora Javy, ale jeśli limit linii to 7627, zastanawiam się, jaki jest limit długości linii;), który może być podobny. to znaczy. limity mogą nie być oparte na liczbie wyliczeń, ale na ograniczeniach długości linii lub liczbie linii w limicie plików, aby zmienić nazwy enum na A, B itp., aby były one bardzo małe, aby zmieścić więcej wyrażeń w wyliczeniu.

Nie mogę uwierzyć, że ktoś napisał xsd z 10 000 enum ... musieli wygenerować tę część xsd.

6

Wyliczenia z pewnością mają ograniczenia, przy czym główny (twardy) limit wynosi około 32K wartości. Podlegają one maksymalnym klasom Java, zarówno "puli stałej" (wpisy 64K) oraz - w niektórych wersjach kompilatorów - do limitu rozmiaru metody (kod bajtowy 64K) na inicjalizatorze statycznym.

Inicjalizacja "Enum" wewnętrznie, wykorzystuje dwie stałe na wartość - łańcuch FieldRef i łańcuch Utf8. Daje to "twardy limit" przy wartościach ~ 32K.

Starsze kompilatory (przynajmniej Eclipse Indigo) również napotkały problem dotyczący statycznego rozmiaru inicjalizatora. Z 24 bajtami kodu bajtowego wymaganego do utworzenia instancji każdej wartości & dodaj ją do tablicy wartości. można napotkać limit około 2730 wartości.

Nowsze kompilatory (przynajmniej JDK 7) automatycznie dzielą duże inicjatory statyczne na metody o nazwach " enum constant initialization$2", " enum constant initialization$3" itd., Więc nie podlegają drugiemu limitowi.

Można zdemontować kod bajtowy za pomocą javap -v -c YourEnum.class, aby zobaczyć, jak to działa.

[Możliwe, że teoretycznie można napisać klasę Enum "starego stylu" jako handcoded Java, aby przełamać limit 32 KB i zbliżyć się do wartości 64K. Podejściem byłoby zainicjowanie wartości wyliczonych przez odbicie, aby uniknąć stałych ciągów w puli. Przetestowałem to podejście i działa ono w języku Java 7, ale celowość takiego podejścia (kwestie bezpieczeństwa) są wątpliwe.]

4

Maksymalna liczba elementów wyliczeniowych to 2746. Czytanie specyfikacji było bardzo mylące i spowodowało, że utworzyłem wadliwy projekt z założeniem, że nigdy nie trafiłbym na znak 64K lub nawet 32K. Niestety, liczba jest znacznie niższa niż wskazuje na to specyfikacja. W ramach testu wypróbowałem następujące elementy zarówno w środowisku Java 7, jak i Java 8: Przeprowadź następujący kod, przekierowując go do pliku, a następnie skompiluj wynikowy plik .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+"}"); 

Wynik, 2746 prac, a 2747 nie.

Po 2746 wpisów, kompilator generuje kod zbyt duży błąd, jak

EnumSizeTest.java:2: error: code too large

Dekodowanie tego pliku klasy Enum, ograniczenie wydaje się być spowodowane przez kod generowany dla każdego wartość enum w statycznym konstruktorze (przeważnie).

+0

Wygląda na to, że w specyfikacji językowej powinno być coś z tego limitu. Kompilator nie może decydować, ile chce na to zezwolić. Jaki komunikat o błędzie dostałeś? – Thilo

+0

Edytowałem post, aby odpowiedzieć na twoje pytanie i dokładniej wyjaśnić moją odpowiedź. Nadzieja, która pomaga. – Derek

+0

Czy używałeś 32-bitowego lub 64-bitowego JDK/JRE? – michaeak

Powiązane problemy