Подтвердить что ты не робот

Максимальное количество элементов перечисления в Java

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

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

4b9b3361

Ответ 1

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

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

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

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

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

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

Ответ 2

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

[ERROR] Не удалось выполнить цель org.apache.maven.plugins: maven-compiler-plugin: 2.0.2: скомпилировать (по умолчанию компиляция) в рамках проекта: сбой компиляции [ERROR]/Users/dhiller/Space/ifp-core/framework/target/generated-sources/com/framework/util/LanguageCodeSimpleType.java:[7627,4] слишком большой

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

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

Ответ 3

У перечислений определенно есть лимиты, с максимальным (жестким) ограничением около 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, чтобы узнать, как это работает.

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

Ответ 4

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

Ответ 5

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

Ответ 6

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

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

Ответ 7

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