Javaの「コードが大きすぎます」コンパイルエラー


94

Javaのコードの最大サイズはありますか?10,000行を超える関数を記述しました。実際、各行は配列変数に値を割り当てます。

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"; 

コンパイル中にこのエラーが発生しました:コードが大きすぎます

どうすればこれを克服できますか?


9
私はただ驚かされています...これを行うためのより良い方法があるに違いありません。
Thanos Papathanasiou 2010年

6
この種のことをデータベースで確認する必要があり、プロパティファイルが失敗します。
ポールウィラン

44
なぜあなたは悪いデザインを貧しい人に怒鳴りつけているのですか?たぶん、OPはなんらかのコード生成ツールでその狂った方法を入手しました。
webuster 2014

14
これらの浅い重要なコメントが非常に多くの賛成票を獲得したことに私は驚いています!
Evgeni Sergeev 2014年

7
コンパイラにコンパイル時にすべてを事前に生成させることができるのに、アプリケーションのスタートアップでテキストファイルを解析して多くの時間を費やすのはなぜですか?再コンパイルせずにデータを変更したり、メソッドを手動で記述したりする場合、これは悪い設計ですが、ソースコードを生成する場合は、まったく悪い設計ではありません。(少なくとも、実際にコンパイラーが配列を事前生成できるようにする場合)。
Guntram Blohmはモニカ

回答:


92

Javaクラスの単一のメソッドは、最大で64KBのバイトコードになる場合があります。

しかし、これを片付ける必要があります!

.propertiesファイルを使用してこのデータを保存し、経由でロードしますjava.util.Properties

これを行うには、.propertiesファイルをクラスパスに配置し、次を使用します。

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

2
「JDK / JVMの実際のサイズに関係なく」?この制限が修正されていないことを意味していますか?これは、クラスファイル形式の仕様で固定され、必須であるためです。
Joachim Sauer

1
.propertiesファイルはどこにありますか
trinity

1
あなたはその後、クラスパス上に置く独自に作成
マーク

3
私はそれを次の時間を試して熱望していますけれども、私は今..この情報を格納するデータベースを使用し、「それに応じて残りのコードを変更しましている..あなたの提案を使用していませんでし
三位一体

1
これが愚かな質問である場合は申し訳ありませんが、..この.propertiesファイルはどこに置く必要がありますか?つまり、それはクラスパスにありますが、どこにありますか?
Milack27

14

メソッドには64Kバイトコードのサイズ制限があります

そうは言っても、私はリチャードと同意しなければなりません。なぜそんなに大きな方法が必要なのですか?OPの例では、プロパティファイルで十分です。必要な場合はデータベースで十分です。


4
列挙型はどうですか?列挙型の大きなセットでも同じ問題が発生します
Toby

1
@Toby:自分自身でこの問題に直面したことはありません。同じ問題について、SOの他のユーザーによる投稿があります。例えば- stackoverflow.com/questions/2546470のための.class生成されたファイルを検討する価値があるかもしれenum参照する
みんな

Enumインスタンス(つまり、定数を表すオブジェクト)は、クラスの静的初期化子で作成されます。これはメソッドであり、同じ制限があります。
juancn 2015

非常に複雑なWebフォームのフレームワーク生成コードで同じ問題に直面しました。解決策は、フォームをコンポーネントに分割することでした。そのため、各コンポーネントに対して生成されたコードも分割されました。
SebaGra

12

Java Virtual Machine仕様によれば、メソッドのコードは65536バイトを超えてはなりません

code_lengthアイテムの値は、codeこのメソッドの配列のバイト数を示します。

code_lengthの値はゼロより大きく(コード配列が空であってはならないため)、65536未満でなければなりません。

code_lengthcode[]メソッドの実際のバイトコードを含む属性のサイズを定義します。

code配列は、メソッドを実装するJava仮想マシン・コードの実際のバイト数を示します。


7

これは少し狂気のようです。テキストファイルまたはその他のデータソースから値を読み取って配列を初期化できませんか?


3
(反対票を投じた理由)これには、このような手法が悪い理由少なくとも1つ必要です。正当な理由を考え出すのは簡単ではありません。
Evgeni Sergeev 2014年

2

コードをリファクタリングしてみてください。Javaではメソッドのサイズに制限があります。


1
リファクタリングは、彼がそのメソッドで行うすべてが配列の初期化である場合、理にかなったアイデアとは言えません。
GabrielŠčerbák10年

2
彼のコードの残りの部分はこれが配列であることに依存していると彼は言った。そのため、彼はメソッドをリファクタリングして、データをファイル/データベースから他のメソッド/ファクトリにロードする責任を渡すことができます。
Padmarag

この種のナンセンスに頼ることなく、大きな配列を作成して初期化できます。@クリスの答えを見てください。
スティーブンC

リファクタリング-「ソフトウェアの非機能属性の一部を改善するために、外部の機能動作を変更せずにコンピュータプログラムのソースコードを変更するプロセス」他の答えはこれとどう違うのですか?
Padmarag 2010年

2

他の回答で述べたように、メソッドには64KBのバイトコード制限があります(少なくともSunのJavaコンパイラでは)。

あまりにも私はそのメソッドをより多くのメソッドに分割する方が理にかなっています-それぞれが特定の関連するものを配列に割り当てます(これを行うためにArrayListを使用する方が理にかなっているかもしれません)

例えば:

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

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

または、プロパティファイルなどから固定されている場合は、静的リソースからアイテムをロードすることもできます。


正解は、データをデータとして扱い、コードをコードとして扱うことです。
Malcolm 14

@Malcolmええと、これは明らかにデータであり、コードではありません。あなたのコメントは誤解を招くものです。なぜなら、すべきでないのはデータとコードを混合することですが、ここではそれらが混合されていないからです。
Evgeni Sergeev 2014年

これは良い回避策だと思います.7000のルートメッセージを含む約21k行のコードでこの問題に遭遇しました。それらのルートメッセージをxxx0 xxx1 xxx2という名前の7つの関数に分割することで修正します。
ブロンズ男

2

私自身もこの問題に遭遇しました。私にとってうまくいった解決策は、メソッドをリファクタリングしてより管理しやすい部分に縮小することでした。あなたと同じように、私は10Kに近い回線方式を扱っています。ただし、静的変数と小さなモジュラー関数を使用することで、問題は解決しました。

より良い回避策があるようですが、Java 8を使用すると何もありません...


2

このエラーは、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();
}

1

別のメソッドを追加して、追加のデータスペース用にコード用のスペースを作成できます。大量のデータスペースを使用するメソッドがある場合があります。私が同じ問題を抱えていたのでメソッドを分割してみて、Java Androidコードで同じデータ用に別の追加メソッドを作成して修正してください。私がそれを実行した後、問題はなくなりました。


これは答えというよりコメントです。
user3071284 2015

0

.javaファイルのサイズが500KBを超える列挙型があります。Eclipseは何らかの理由でそれをビルドできます。Eclipseでエクスポートされたant build.xmlはできません。私はこれを調査しており、この投稿を更新します。


0

メソッドにはサイズ制限があり、この時点でコードを再設計したくないので、配列を4〜5の部分に分割して、それらを別のメソッドに配置することができます。配列を読み取るときに、一連のすべてのメソッドを呼び出します。解析したインデックスの数を知るために、カウンターも維持できます。


0

これは、単一のメソッドソリューションのすべてのコードが原因です。いくつかの小さなメソッドを作成すると、このエラーはなくなります


0

はい、多分この答えは手遅れですが、私はこの方法が他の方法よりも優れていると思います

たとえば、コードには1000行のデータがあります

  1. それらを壊す

    private void rows500() {
         //you shoud write 1-500 rows here
    }
    
    private void rows1000() {
         you shoud write 500-1000 rows here
    }
  2. パフォーマンスを向上させるには、コードに「if」を挿入します

    if (count < 500) {
        rows500();
    } else if (count > 500) {
        rows1000();
    }

このコードがあなたに役立つことを願っています

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.