たとえば、次のコードをご覧ください。
System.out.println("Hello World!");
getstatic(静的フィールドSystem.outをロードする)、ldc(定数文字列「Hello World!」をロードする)、invokevirtual(println仮想関数を実行する)の3つのバイトコード命令に変換されます。 このコードが機能するために必要な定数の数を把握してください。
この行は14の定数を使用していることがわかります。

ご覧のとおり、ほとんどの定数は他の定数への参照です。 各定数には、参照可能な型、値、および番号があります。 以下は、何も参照しない基本タイプです。
- 整数は整数です。 これらは、番号が必要なコードから参照されます。 コンパイラが追加しない-32768から32767までの数値:指示iconst_ x 、bipushおよびsipushを使用してコード内で明示的に指定できます。
- Longは長整数です。 歴史的な理由により、定数プール内の2つの位置を占有します(つまり、次の定数にはさらに2つの数値があります)。 lconst_ xで保存できるのは0Lと1Lのみです。 2Lはすでにプールにあります。
- フロート-単精度素材。 特別な指示fconst_ xは0.0f、1.0fおよび2.0f用です。 使用される残りの番号はプール内にあります。
- 倍精度-実倍精度。 ロングと同様に、プール内の2つの位置を占有します。 dconst_ x命令を使用してプールなしで使用できるのは、数字0.0と1.0のみです。
- Utf8は、Utf8でエンコードされた文字列リテラルです。 最大長は65535バイトを超えません(もちろん、文字はこれより少ない場合があります)。 これらのリテラルは、ほとんどの場合、他の定数から参照されます。
参照タイプの一部を次に示します。
- 文字列は文字列です。 Utf8などの定数への参照が含まれます。 コードで文字列を使用する場合、文字列型の定数を参照しています。 余分なエンティティのように見えますが、そうです。
- NameAndType-フィールドまたはメソッドの名前とタイプを記述する定数。 名前とタイプを持つUtf8定数への2つの参照が含まれます。
- クラスは、クラスまたはインターフェイスの名前を記述する定数です。 内部クラス名を持つUtf8定数への参照が含まれます。
- Fieldrefは、特定のクラスの特定のフィールドを記述する定数です。 Class定数への参照とNameAndType定数へのリンクが含まれています。
- MethodRef、InterfaceMethodRef-クラスまたはインターフェイスの特定のメソッドを記述する定数。 Class定数およびNameAndType定数への参照が含まれます。
フィールドにアクセスするには、その名前だけでなく、フィールドが宣言されているクラスのフルネーム、およびフィールドのタイプも必要です。 メソッドにアクセスするには、メソッドのクラス、名前、および署名が必要です。 幸い、メソッドパラメーターの数に関係なく、署名全体が1行でエンコードされます。プリミティブ型は1文字(たとえばD = double)でエンコードされ、オブジェクトは文字Lで、その後に完全なクラス名とセミコロンが続き、1レベルの配列が追加されます角かっこ。 引数のタイプは括弧で囲まれ、戻り値のタイプが続きます(Vは無効です)。 たとえば、署名
(IDLjava/lang/Thread;)Ljava/lang/Object;
このメソッドには次のものがあります。
Object m(int i, double d, Thread t) {...}
メソッドを参照するには正確な署名が必要であるという事実から、開発者はNoSuchMethodErrorに遭遇することがあります。 メソッドの戻り値の型をより具体的なものに変更したとしましょう。 その後、他のクラスからのこのメソッドへの呼び出しは同じままであり、ソースファイルが変更されていないため、コンパイラはこれらのクラスを再コンパイルしません。 ただし、実行時にこのメソッドを呼び出そうとすると、Javaマシンは古い署名を探します。
Javaコードを自動的に生成する場合は、プール内の最大定数が65535を超えないようにしてください。その後、コンパイルエラーが発生します。 膨大な数のリンクと、長くて二重の2つの位置を占めるという事実を考えると、これはそれほど多くありません。 プールデバイスを知ることは、コードを生成する際にプールデバイスを制御するのに役立ちます。
定数プールデバイスの詳細については 、Java Virtual Machine仕様の§4.4を参照してください。