Максимальное количество элементов перечисления в Java - PullRequest
26 голосов
/ 17 декабря 2010

Какое максимальное количество элементов разрешено в перечислении в Java?

Я хотел узнать максимальное количество случаев в операторе switch.Поскольку самый большой тип примитива, разрешенный в switch, это int, у нас есть случаи от -2 147 483 648 до 2 147 483 647 и один случай по умолчанию.Однако перечисления также допускаются ... так что вопрос ..

Ответы [ 7 ]

31 голосов
/ 17 декабря 2010

Из спецификации формата файла класса :

Пул констант для каждого класса или интерфейса ограничен 65535 записями 16-битным полем constant_pool_count структуры ClassFile (§4.1). Это действует как внутреннее ограничение общей сложности одного класса или интерфейса.

Я считаю, что это означает, что вы не можете иметь более 65535 именованных «вещей» в одном классе, что также ограничило бы число констант перечисления.

Если я увижу коммутатор с 2 миллиардами дел, я, вероятно, убью любого, кто коснулся этого кода.

К счастью, этого не может быть:

Количество кода на не собственный, неабстрактный метод ограничено 65536 байтами размерами индексов в таблице исключений атрибута кода (§4.7.3) в атрибуте LineNumberTable (§4.7.8 ) и в атрибуте LocalVariableTable (§4.7.9).

11 голосов
/ 02 марта 2017

Максимальное количество элементов enum - 2746. Чтение спецификации очень вводило в заблуждение и заставило меня создать некорректный дизайн с предположением, что я никогда не достигну отметки 64К или даже 32К.К сожалению, число намного ниже, чем указывает спецификация.В качестве теста я попробовал следующее с Java 7 и Java 8: запустил следующий код, перенаправив его в файл, затем скомпилировал полученный файл .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+"}");

Результат, 2746 работ и 2747не.

После 2746 записей компилятор выдает код слишком большой ошибки, например

EnumSizeTest.java: 2: ошибка: код слишком большой

При декомпиляции этого файла класса Enum ограничение, по-видимому, вызвано кодом, сгенерированным для каждого значения перечисления в статическом конструкторе (в основном).

7 голосов
/ 17 декабря 2014

Перечисления определенно имеют ограничения, с основным (жестким) ограничением около 32К значенийНа них распространяются максимумы класса Java как на «постоянный пул» (записи 64 КБ), так и - в некоторых версиях компилятора - на ограничение размера метода (64 КБ байт-кода) на статическом инициализаторе.

'Enumвнутренняя инициализация, использует две константы для каждого значения - FieldRef и строку Utf8.Это дает «жесткий предел» в значениях ~ 32K.

Старые компиляторы (по крайней мере, Eclipse Indigo) также сталкиваются с проблемой размера метода статического инициализатора.С 24 байтами байтового кода требуется для создания экземпляра каждого значения и добавления его в массив значений.может встретиться ограничение в 2730 значений.

Более новые компиляторы (по крайней мере, JDK 7) автоматически разбивают большие статические инициализаторы на методы с именами " enum constant initialization$2", " enum constant initialization$3" и т. д., поэтому не подпадают под второе ограничение.

Вы можете разобрать байт-код с помощью javap -v -c YourEnum.class, чтобы увидеть, как это работает.

[Теоретически возможно написать класс Enum "старого стиля" как Java-код с ручной кодировкой, чтобы разбить 32Kограничить и приблизиться к значениям 64К.Подход заключается в том, чтобы инициализировать значения перечисления отражением , чтобы избежать необходимости использования строковых констант в пуле.Я протестировал этот подход, и он работает в Java 7, но желательность такого подхода (вопросы безопасности) сомнительны.]

Примечание для редакторов: Utf8 был внутренним типом в файле классов Java IIRC,это не опечатка, которую нужно исправить.

7 голосов
/ 12 мая 2012

Ну, на jdk1.6 я достиг этого предела.У кого-то есть 10 000 перечислений в xsd, и когда мы генерируем, мы получаем файл с перечислением 60000 строк, и я получаю хорошую ошибку компилятора java

[ОШИБКА] Не удалось выполнить цель org.apache.maven.plugins: maven-compiler-plugin: 2.0.2: компилировать (по умолчанию-компилировать) на платформе проекта: ошибка компиляции [ОШИБКА] / Пользователи / dhiller / Space / ifp-core / framework / target / генерируемые источники / com / framework / util / LanguageCodeSimpleType.java: [7627,4] код слишком велик

, поэтому вполне возможно, что предел намного ниже, чем другие ответы здесь, ИЛИ может быть, комментарии и тому подобные, занимающие слишком много места.Обратите внимание, что номер ошибки 7627 в ошибке компилятора Java, хотя, если предел строки 7627, мне интересно, каков предел длины строки;), который может быть похожим.то есть.ограничения могут быть не основаны на количестве перечислений, но ограничены длиной строк или количеством строк в ограничении файла, поэтому вы должны будете переименовать перечисления в A, B и т. д., чтобы они были очень маленькими, чтобы вписать в перечисление больше перечислений.

Не могу поверить, что кто-то написал xsd с перечислением 10000 ... они, должно быть, сгенерировали эту часть xsd.

3 голосов
/ 17 декабря 2010

Максимальный размер любого метода в Java составляет 65536 байт.Хотя теоретически вы можете иметь большой переключатель или большее количество значений перечисления, это максимальный размер метода, который вы, вероятно, нажмете первым.

2 голосов
/ 17 декабря 2010

Класс Enum использует int для отслеживания порядкового номера каждого значения, поэтому max будет в лучшем случае таким же, как int, если не намного ниже.

И, как уже говорили другие, если вам нужно спросить, вы делаете это неправильно

0 голосов
/ 17 декабря 2010

Не существует максимального числа per se для любых практических целей.Если вам нужно определить тысячи перечислений в одном классе, вам нужно переписать вашу программу.

...