1. 概要 

J avaメソッドが65535バイトを超えると、「コードが大きすぎます」というコンパイルエラーが発生します。 この記事では、このエラーが発生する理由とその修正方法について説明します。

2. JVMの制約

Code_attribute は、JVM仕様のmethod_info構造体の可変長のテーブルです。 この構造には、メソッドの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パーサーなどのコードジェネレーターを使用した結果です。
  • 初期化方法:GUIの初期化では、レイアウト、イベントリスナーなど、多くの詳細をすべて1つの方法で追加できます。
  • JSPページ:クラスの1つのメソッドにすべてのコードが含まれています
  • Code Instrumentation :実行時にコンパイルされたクラスにバイトコードを追加します
  • 配列イニシャライザー:以下に示すように、非常に大きな配列を初期化するメソッド:
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. 結論

この記事では、「コードが大きすぎる」エラーの原因と考えられる解決策について説明しました。 この制約の詳細については、JVM仕様Code_Attributesセクションをいつでも参照できます。