2010-03-09 3 views
70

Gibt es eine maximale Größe für Code in Java? Ich habe eine Funktion mit mehr als 10.000 Zeilen geschrieben. Tatsächlich weist jede Zeile einer Array-Variablen einen Wert zu."Code zu groß" Kompilierungsfehler in 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"; 

Und beim Kompilieren, bekomme ich diesen Fehler: Code zu groß

Wie kann ich dies zu überwinden?

+22

OMG O_O ... das ist wirklich ein SCHLECHTE, SCHLECHTE, SCHLECHTE Design ... –

+4

Ich bin nur fassungslos ... Es gibt eine bessere Möglichkeit, dies zu tun. –

+2

Ja, ja, ich stimme zu - das Design ist hoffnungslos. Anfangs war die Größe des Arrays nur 64, also habe ich nicht die Notwendigkeit gefunden, aus einer Datei zu lesen. Jetzt hängt der Rest des Codes davon ab, dass es sich um ein Array handelt, also dachte ich, ich könnte eine temporäre Lösung bekommen und später Ordne Dinge durch Lesen aus einer Datei. Okay, ich werde deine Vorschläge versuchen, danke! – trinity

Antwort

72

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

Aber Sie sollten dies aufräumen!

Verwenden .properties Datei diese Daten zu speichern, und laden Sie es über java.util.Properties

Sie können dies tun, indem Sie die .properties Datei auf Ihrem Classpath platzieren und Verwendung:

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

"Egal, was die tatsächliche Größe für Ihr JDK/JVM ist"? Meinst du, dass diese Grenze nicht festgelegt ist? Weil es durch die Spezifikation des Klassendateiformats festgelegt und benötigt wird. –

+0

Ich wusste nicht, dass es repariert ist, danke für die Klarstellung. – Bozho

+1

wo finde ich die Datei .properties – trinity

9

Dies scheint ein bisschen wie Wahnsinn. Können Sie das Array nicht initialisieren, indem Sie die Werte aus einer Textdatei oder einer anderen Datenquelle lesen?

+1

(Downvoted weil) Dies benötigt mindestens einen Grund, warum eine solche Technik schlecht ist. Es ist nicht einfach, einen guten Grund zu finden. –

11

Es ist ein 64K byte- code size limit on a method

Nachdem ich das gesagt habe, muss ich w/Richard zustimmen; Warum brauchst du eine so große Methode? Angesichts des Beispiels im OP sollte eine Eigenschaftendatei ausreichen ... oder sogar eine Datenbank, falls erforderlich.

+1

Wie wäre es mit enums? Ich bekomme das gleiche Problem mit großen Mengen von Enums – Toby

+0

@Toby: Nie mit diesem Problem konfrontiert mit enum mich. Es gibt Beiträge von anderen Benutzern hier auf SO etwa das gleiche Problem. Zum Beispiel - http://stackoverflow.com/questions/2546470/ Es kann sich lohnen, in die generierte .class-Datei nach einer 'enum' zu suchen, um – Everyone

+0

Enum-Instanzen (dh die Objekte, die die Konstanten repräsentieren) zu erstellen Der statische Initialisierer der Klasse ist eine Methode und hat die gleiche Einschränkung. – juancn

3

Versuchen Sie, Ihren Code zu refaktorieren. Die Größe der Methode in Java ist begrenzt.

+1

Refactoring naht nicht als eine vernünftige Idee, wenn alles, was er in dieser Methode tut Array-Initialisierung ist. –

+2

Er sagte, dass der Rest seines Codes davon abhängt, dass dies ein Array ist. So konnte er die Methode umgestalten, um die Verantwortung für das Laden von Daten auf eine andere Methode/Factory aus Datei/Datenbank zu übernehmen. – Padmarag

+0

können Sie große Arrays erstellen und initialisieren, ohne auf diese Art von Unsinn zurückgreifen zu müssen; siehe @ Kris Antwort. –

2

Wie in anderen Antworten erwähnt, gibt es für ein Verfahren ein 64KB von Bytecode-Grenze ist (zumindest in Suns Java-Compiler)

mich Too es mehr Sinn machen würde, diese Methode zu brechen in mehrere Verfahren - jeder Zuweisung bestimmter verwandte Themen auf das Array (vielleicht mehr Sinn machen, eine Arraylist zu verwenden, dies zu tun)

zum Beispiel: Sie könnten die Elemente aus einer statischen Ressource laden, wenn sie befestigt sind, wie aus einer Eigenschafts

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

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

Alternativ Datei

+0

Korrekte Antwort ist, Daten als Daten und Code als Code zu behandeln. – Malcolm

+0

@ Malcolm Nun, das ist eindeutig Daten und nicht Code. Ihr Kommentar ist irreführend, denn was Sie nicht tun sollten, ist _mix_ Daten und Code, aber hier sind sie nicht gemischt. –

+0

Ich denke, das ist eine gute Arbeit um.Ich komme mit diesem Problem mit etwa 21k Zeilen Code mit 7000 Route Nachrichten in it.I beheben es durch div diese Route Nachrichten in 7 Funktion mit Namen xxx0 xxx1 xxx2. –

9

Nach dem Java Virtual Machine specification, ein the code of a method must not be bigger than 65536 bytes:

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

Wo code_length in §4.7.3 The Code Attribute definiert:

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

Wow, das ist schlecht. Hard-Coding-Daten in Ihrem Programm ist nie eine gute Idee überhaupt. Harte Codierung eine Tonne von Daten ist nicht besser und verursacht, dass Sie in den Beschränkungen in anderen Antworten beschrieben zu laufen.

Es gibt eine Reihe von Möglichkeiten, um dies zu beheben, aber die folgenden sollten keinen anderen Code brechen.

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 schafft das Verfahren (und kehrt zurück, aber es konnte diese so leicht eine Klassenvariable Bearbeiten) eine Anordnung, die jede Zeile der Datei enthält, um.

Speichern Sie einfach die Werte in Ihrem Quellbeispiel (z. B. "newyorkartworld") in eine Textdatei - in dieser Reihenfolge - und laden Sie damit das Array.

Während dieser einfache Tropfen in Ersatz funktioniert, gibt es viel elegantere Lösung da draußen, wenn Sie die Zeit finden, ein wenig Refactoring zu tun.

+0

(Downvoted :) "Warum das schlecht ist wurde schon erklärt." Ich kann die Erklärung nicht finden. Kannst du es verlinken? –

0

Ich habe selbst auf dieses Problem gestoßen. Die Lösung, die für mich funktionierte, bestand darin, die Methode zu überschaubaren Stücken umzuformen und zu verkleinern. Wie Sie, habe ich es mit einer fast 10K Zeilen Methode zu tun. Mit der Verwendung von statischen Variablen sowie kleineren modularen Funktionen wurde das Problem jedoch gelöst.

scheint es wäre eine bessere Abhilfe, aber unter Verwendung von Java 8, gibt es keine ...

1

Sie eine andere Methode Platz für Ihren Code für zusätzlichen Datenraum zu schaffen hinzufügen können, können Sie eine Methode, die ist eine große Menge an Datenraum nehmen. Versuchen Sie, Ihre Methoden zu teilen, weil ich das gleiche Problem hatte, und beheben Sie es, indem Sie eine weitere Methode für die gleichen Daten in meinem Java-Code erstellen. Das Problem war weg, nachdem ich das getan hatte.

+0

Dies ist eher ein Kommentar als eine Antwort. – user3071284

-1

Dieser Fehler manchmal aufgrund auftreten zu groß Code in einer einzigen Funktion ... Um diesen Fehler zu beheben, diese Funktion in mehreren Funktionen geteilt, wie

//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(); 
} 
Verwandte Themen