Перейти к основному содержимому

Ошибка компиляции «Слишком большой код» в Java

· 3 мин. чтения

1. Обзор

Когда метод Java превышает 65535 байт, мы получаем ошибку компиляции «слишком большой код» . В этой статье мы обсудим, почему возникает эта ошибка и как ее исправить.

2. Ограничения JVM

Code_attribute — это таблица переменной длины в структуре method_info спецификаций JVM. Эта структура содержит инструкции JVM для метода, который может быть обычным методом или методом инициализации экземпляра, класса или интерфейса:

Code_attribute {
u2 attribute_name_index;
u4 attribute_length;
u2 max_stack;
u2 max_locals;
u4 code_length;
u1 code[code_length];
u2 exception_table_length;
{
u2 start_pc;
u2 end_pc;
u2 handler_pc;
u2 catch_type;
}
exception_table[exception_table_length];
u2 attributes_count;
attribute_info attributes[attributes_count];
}

Атрибут code_length указывает длину кода в методе:

code_length
The value of the code_length item gives the number of bytes in the code array for this method.
The value of code_length must be greater than zero (as the code array must not be empty) and less than 65536.

Как видно выше, в спецификациях JVM указано, что длина кода метода должна быть меньше 65536 байт, поэтому это означает, что размер метода не может превышать 65535 байт .

3. Почему возникает проблема

Теперь, когда мы знаем предельный размер методов, давайте рассмотрим ситуации, которые могут привести к таким большим методам:

  • Генераторы кода: большинство больших методов являются результатом использования какого-либо генератора кода, такого как парсер ANTLR.
  • Методы инициализации: инициализация графического интерфейса может добавлять множество деталей, таких как макеты, прослушиватели событий и многое другое, все в одном методе.
  • Страницы JSP: содержат весь код в одном методе класса.
  • Инструментарий кода: добавляет байт-код в скомпилированные классы во время выполнения.
  • Инициализаторы массивов: методы инициализации очень больших массивов, как показано ниже:
String[][] largeStringArray = new String[][] {
{ "java", "code", "exceeded", "65355", "bytes" },
{ "alpha", "beta", "gamma", "delta", "epsilon" },
{ "one", "two", "three", "four", "five" },
{ "uno", "dos", "tres", "cuatro", "cinco" },

//More values
};

4. Как исправить ошибку

Как мы уже отмечали, основной причиной ошибки является метод, превышающий порог в 65535 байт. Таким образом, рефакторинг ошибочного метода на несколько более мелких методов решит проблему для нас.

В случае инициализации массивов мы можем либо разделить массивы, либо загрузить их из файла. Мы также можем использовать статические инициализаторы . Даже когда мы используем генераторы кода, мы все равно можем реорганизовать код. А в случае большого файла JSP мы можем использовать директиву j sp:include и разбить его на более мелкие части.

Вышеупомянутые проблемы относительно легко решить, но все усложняется, когда мы получаем ошибку «слишком большой код» после добавления инструментовки в код . Если код принадлежит нам, мы все равно можем реорганизовать метод. Но когда мы получаем эту ошибку из сторонней библиотеки, мы исправляемся. Уменьшив уровень инструментовки, мы могли бы решить проблему.

5. Вывод

В этой статье мы обсудили причины и возможные решения ошибки «Слишком большой код». Мы всегда можем обратиться к разделу Code_Attributes спецификаций JVM , чтобы найти более подробную информацию об этом ограничении.