2010-03-09 3 views
70

Есть ли максимальный размер кода в Java? Я написал функцию с более чем 10 000 строк. Фактически, каждая строка присваивает значение переменной массива.Ошибка «Code too large» в Java

 arts_bag[10792]="newyorkartworld"; 
     arts_bag[10793]="leningradschool"; 
     arts_bag[10794]="mailart"; 
     arts_bag[10795]="artspan"; 
     arts_bag[10796]="watercolor"; 
     arts_bag[10797]="sculptures"; 
     arts_bag[10798]="stonesculpture"; 

И во время компиляции, я получаю эту ошибку: код слишком большой

Как это преодолеть?

+22

OMG O_O ... это действительно BAD, BAD, BAD design ... –

+4

Я просто ошеломлен ... Там должен быть лучший способ сделать это. –

+2

Да, да, я согласен - дизайн безнадежен. Первоначально размер массива был всего 64, поэтому я не нашел необходимости читать из файла. Теперь остальная часть кода зависит от того, что это массив, поэтому я подумал, что могу получить временное решение, а затем позже упорядочивать вещи, читая из файла. хорошо, попробую свои предложения, спасибо! – trinity

ответ

72

A single method in a Java class may be at most 64KB of bytecode.

Но вы должны очистить это!

Использование .properties файла для хранения этих данных, и загрузить его через java.util.Properties

Вы можете сделать это, поместив файл .properties на вашем пути к классам и используйте:

Properties properties = new Properties(); 
InputStream inputStream = getClass().getResourceAsStream("yourfile.properties"); 
properties.load(inputStream); 
+2

«Независимо от фактического размера вашего JDK/JVM»? Вы подразумеваете, что этот предел не исправлен? Потому что это исправлено и требуется по спецификации формата файла класса. –

+0

Я не знал, что это исправлено, спасибо за разъяснение. – Bozho

+1

Где я могу найти файл .properties – trinity

9

Это похоже на безумие. Не можете ли вы инициализировать массив, читая значения из текстового файла или другого источника данных?

+1

(Downvoted, потому что) Для этого нужна хотя бы одна причина: почему такая техника плохая. Нелегко придумать вескую причину. –

11

Существует 64К байт- ограничение по размеру кода на method

Сказав это, я должен согласиться с Ричардом; зачем вам нужен такой метод? Учитывая пример в OP, файл свойств должен быть достаточным ... или даже базу данных, если это необходимо.

+1

как насчет перечислений? я получаю ту же проблему с большими наборами перечислений – Toby

+0

@Toby: Никогда не сталкивался с этой проблемой с перечислением. Тем не менее, есть сообщения других пользователей здесь о SO о том же вопросе. Например, http://stackoverflow.com/questions/2546470/ Возможно, стоит посмотреть в сгенерированный файл .class для 'enum', чтобы увидеть – Everyone

+0

экземпляры Enum (т.е. объекты, представляющие константы), создаются в статический инициализатор класса, который является методом и имеет такое же ограничение. – juancn

3

Попробуйте реорганизовать свой код. В Java существует ограничение на размер метода.

+1

Рефакторинг не является швом как разумная идея, если все, что он делает в этом методе, является инициализацией массива. –

+2

Он сказал, что остальная часть его кода зависит от того, что это массив. Поэтому он мог бы реорганизовать метод, чтобы передать ответственность за загрузку данных на другой метод/Factory из файла/базы данных. – Padmarag

+0

вы можете создавать и инициализировать большие массивы, не прибегая к такой чепухе; см. ответ Криса. –

2

Как уже упоминалось в других ответах есть 64KB предела байт-кода для метода (по крайней мере в Java компилятор компании Sun)

Слишком меня было бы больше смысла, чтобы сломать этот метод на большее методы - каждый назначая определенный связанные вещи в массив (может иметь больше смысла использовать ArrayList, чтобы сделать это)

, например:

public void addArrayItems() 
{ 
    addSculptureItems(list); 
    ... 
} 

public void addSculptureItems(ArrayList list) 
{ 
    list.add("sculptures"); 
    list.add("stonesculpture"); 
} 

в качестве альтернативы вы можете загрузить элементы из статического ресурса, если они зафиксированы как из свойств файл

+0

Правильный ответ - рассматривать данные как данные и код как код. – Malcolm

+0

@Malcolm Ну, это явно данные, а не код. Ваш комментарий вводит в заблуждение, потому что вы не должны делать это _mix_ данные и код, но здесь они не смешиваются. –

+0

Я думаю, что это хорошая работа. Я столкнулся с этой проблемой примерно с 21 тыс. Строк кода с 7000 сообщениями маршрута в нем. Я исправляю это, разделив эти сообщения маршрута на 7-ю функцию с именем xxx0 xxx1 xxx2. –

9

Согласно Java Virtual Machine specification, the code of a method must not be bigger than 65536 bytes:

The value of the code_length item must be less than 65536.

code_length Где определяется в §4.7.3 The Code Attribute:

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; the code array must not be empty.

code[] : The code array gives the actual bytes of Java virtual machine code that implement the method.

3

Ого, это плохо. Жесткие данные кодирования в вашей программе никогда не являются хорошей идеей в первую очередь. Жесткое кодирование a ton данных не лучше, и вы сталкиваетесь с ограничениями, описанными в других ответах.

Существует несколько способов исправить это, но следующее не должно нарушать какой-либо другой код.

public static String[] getTheArrayThing(){ 
    List<String> list = new LinkedList<String>(); 
    try { 
     BufferedReader br = new BufferedReader(new FileReader(<the file>)); 
     String line = br.readLine(); 
     while (line != null) { 
      list.add(line); 
      line = br.readLine(); 
     } 

    } catch (Exception e){ 
     throw new IllegalStateException("Couldn't load array file"); 
    } 
    return list.toArray(new String[0]); 
} 

Bascially метод создает (и возвращается, но он может так же легко изменить переменный класс) массив, содержащий каждую строку файла в порядке.

Просто введите значения в исходном примере (например, «newyorkartworld») в текстовый файл - в порядке - и используйте это для загрузки массива.

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

+0

(Downvoted, потому что :) «Почему это плохо уже объяснено». Я не могу найти объяснения. Вы можете ссылаться на него? –

0

Я сам столкнулся с этой проблемой. Решение, которое сработало для меня, состояло в том, чтобы реорганизовать и сжать метод до более управляемых частей. Как и вы, я имею дело с методом линии 10K. Однако с использованием статических переменных и небольших модульных функций проблема была решена.

Кажется, было бы лучше, обходной путь, но с использованием Java 8, нет ни ...

1

Вы можете добавить еще один метод, чтобы создать пространство для вашего кода для дополнительного пространства данных, вы можете иметь метод, который занимая большое количество пространства данных. Попробуйте делить свои методы, потому что у меня была такая же проблема, и исправить ее, создав еще один дополнительный метод для одних и тех же данных в моем java-коде Android. Проблема исчезла после того, как я это сделал.

+0

Это скорее комментарий, чем ответ. – user3071284

-1

Эта ошибка иногда возникает из-за слишком большой код в одной функции ... Чтобы решить эту ошибку, разделить эту функцию в нескольких функциях, как

//Too large code function 
private void mySingleFunction(){ 
. 
. 
2000 lines of code 
} 
//To solve the problem 
private void mySingleFunction_1(){ 
. 
. 
500 lines of code 
} 
private void mySingleFunction_2(){ 
. 
. 
500 lines of code 
} 
private void mySingleFunction_3(){ 
. 
. 
500 lines of code 
} 
private void mySingleFunction_4(){ 
. 
. 
500 lines of code 
} 
private void MySingleFunction(){ 
mySingleFunction_1(); 
mySingleFunction_2(); 
mySingleFunction_3(); 
mySingleFunction_4(); 
}