1. Java クラス ファイルとは何ですか?
Java クラス ファイルは Java プログラムのバイナリ表現です。各クラス ファイルはクラスまたはインターフェイスを表します。複数のクラスまたはインターフェイスを 1 つのクラス ファイルに含めることはできません。これにより、クラス ファイルが生成されたプラットフォームに関係なく、任意のホストでクラス ファイルを実行できるようになります。
クラス ファイルは Java アーキテクチャの一部ですが、Java 言語と切り離せないわけではありません。他の言語のプログラムをクラス ファイルにコンパイルしたり、Java プログラム ファイルを他のバイナリ形式にコンパイルしたりできます。
Java クラス ファイルは、8 ビット バイトに基づくバイナリ ストリームです。データ ブロックは、シーケンシャルで区切り文字のないビッグ エンディアン形式で保存されます。
2. クラスファイルの内容
Java クラス ファイルには、Java 仮想マシンに必要なクラスとインターフェイスに関するすべての情報が含まれています。すべてのクラス ファイルの情報は、次の 4 つの基本タイプで保存されます:
表 6-1. クラス ファイルの主要部分は、表 6-2 の順序で保存されます。テーブル
タイプ 名前 数
u4 マジック 1
u2 マイナーバージョン 1
u2 メジャーバージョン 1
u2 constant_pool_count 1
cp_info constant_pool constant_pool_count-1
u2 access_flags 1
u2 this_class 1
u2 super_class 1
u2 Interfaces_count 1
u2インターフェースinterfaces_count
u2 フィールド数 1
フィールド情報フィールド フィールド数
u2 メソッド数 1
メソッド情報メソッド メソッド数
u2 属性_カウント 1
属性情報属性_カウント
1. マジック エンコーディング (マジック)
すべての Java クラス ファイルの最初の 4 バイトはマジック エンコーディング (OxCAFEBABE) です。クラス ファイルは、マジック エンコーディングによって簡単に識別できます。
2.minor_version と Major_version (minor_version と Major_version)
残りの 4 バイトは、マイナー バージョン番号とメジャー バージョン番号です。ただし、Java テクノロジーが進化するにつれて、いくつかの新しい機能がクラス ファイルに追加される可能性があります。クラス ファイルの形式が変更されるたびに、バージョン番号もそれに応じて変更されます。仮想マシンは、バージョン番号を使用して、処理できるクラス ファイルを識別します。 Java 仮想マシンは、多くの場合、特定のメジャー バージョン番号とその下のいくつかのマイナー バージョン番号のみを処理できます。仮想マシンは、処理の範囲外になったクラス ファイルを拒否する必要があります。
3. Constant_pool_count と constant_pool
次は定数プールです。定数プールには、文字列、定数 (最終変数値)、クラス名、メソッド名など、クラスまたはインターフェイスによってアクセスされた定数が含まれます。定数プールはリストとして保存されます。リスト内の定数の数は、以前に保存された「constant_pool_count」です。
定数プール内の多くの定数は、定数プール内の他の定数を参照しており、定数プールの定数への参照は、最終的には定数プール内の定数への直接参照に変換されます。定数リストのインデックスは 1 から始まりますが、定数の数には 0 が含まれます。たとえば、定数リストに定数が 15 個ある場合、定数の数は 16 になります。
すべての定数には、その型を示すフラグが先頭にあります。仮想マシンがこのフラグを読み取ると、この定数の特定のタイプがわかります。表 6-3 にこれらのフラグを示します。
表 6-3. 定数プールのタグ エントリ タイプ タグ値 説明
CONSTANT_Utf8 1 UTF-8 でエンコードされた Unicode 文字列 CONSTANT_Integer 3 int リテラル値
CONSTANT_Float 4 float リテラル値
CONSTANT_Long 5 longリテラル値
CONSTANT_Double 6 double リテラル値 CONSTANT_Class 7 クラスまたはインターフェイスへのシンボリック参照
CONSTANT_String 8 文字列リテラル値 CONSTANT_Fieldref 9 フィールドへのシンボリック参照
CONSTANT_Methodref 10 クラスで宣言されたメソッドへのシンボリック参照
CONSTANT_InterfaceMethodref 11 インターフェイスで宣言されたメソッドへのシンボリック参照
CONSTANT_NameAndType 12 オブジェクトへのシンボリック参照の一部フィールドまたはメソッド
表 6-3 の各フラグには、このフラグによって表される特定の情報を説明する対応するテーブルがあり、これらの対応するフラグはフラグ名 +_INFO で終わります。たとえば、CONSTANT_CLASS フラグは CONSTANT_CLASS_INFO に対応します。
定数プールは、プログラムの動的リンクにおいて非常に重要な役割を果たします。定数プールには、上記のさまざまな定数値に加えて、クラスとインターフェイスの完全名、フィールド名と記述子、メソッド名と記述子の 3 種類のシンボル参照が含まれています。フィールドはクラスまたはインターフェイスのインスタンスまたはクラス変数であり、フィールド記述子はフィールドの型です。メソッド記述子は、メソッドの番号、順序、タイプ、および戻り値とパラメータです。これらの完全名は、このクラスまたはインターフェイスを他のクラスまたはインターフェイスにリンクするときに、仮想マシンによって使用されます。クラス ファイルにはメモリ構造に関する情報が含まれていないため、このリンクはシンボリック参照の形式でのみ存在できます。仮想マシンは、実行中にこれらのシンボリック参照を実際のアドレスに変換します。詳細については、第 8 章「リンク モデル」を参照してください。
4. アクセス フラグ (access_flags)
定数プールの直後の 2 バイトは、このクラスまたはインターフェイスに関する情報のいくつかの側面を表すアクセス フラグです。
表 6-4. access_flags のフラグ ビット。 ClassFile テーブルの項目
フラグ名 値 設定する場合の意味 設定方法
ACC_PUBLIC 0x0001 タイプは public クラスとインターフェイス
ACC_FINAL 0x0010 クラスは Final クラスのみ
ACC_SUPER 0 x0020 新しい invokespecial semantics クラスとインターフェイスを使用します
ACC_INTERFACE 0x0200 タイプはインターフェイスです。 class すべてのインターフェイス、クラスなし
ACC_ABSTRACT 0x0400 型は抽象です すべてのインターフェイス、一部のクラス
ACC_SUPER フラグは、古い SUN コンパイラとの互換性のためのものです。未使用のアクセス フラグはすべて 0 に設定する必要があります。
5. クラス名 (this_class)
次の 2 バイトには、定数プールのインデックスが格納されます。この定数プール内のエンティティは、フラグと名前のインデックスを含む CONSTANT_CLSS_INTO タイプである必要があります。フラグは CONSTATN_CLASS で、名前インデックスは、クラスまたはインターフェイスの完全名を格納する CONSTANT_UTF8_INFO 型のインデックスである必要があります。
6. 親クラス (super_class)
this_class の後には 2 バイトの super_class が続きます。これは、親クラスのフルネームを格納する定数プールのインデックスでもあり、this_class と同じように処理されます。親クラスが java.lang.Object の場合、super_class は 0 である必要があります。インターフェイスの場合、super_class は 0 です。
7. (interfaces_countとinterfaces)
Interfaces_countは親インターフェースの数を格納し、interfacesはいくつかの定数プールインデックスを配列の形式で格納します。各インデックスは、各親インターフェイスの完全名を格納する CONSTANT_CLASS_INFO 定数を指します。この配列の順序は、親インターフェイスがimplements および extends ステートメントに現れる左から右の順序です。
8. (fields_count と field)
フィールドは field_info のリストに保存され、fields_count はこのリストの長さです。 Field_info リストには、クラスまたはインターフェイスで宣言された変数のみが保存されます。親クラスまたは親インターフェイスから継承されたフィールドは、ここには保存されません。
field_info テーブルの各エントリは、フィールド名、記述子、アクセス許可などのフィールドの情報を記述します。フィールドがfinalと宣言されている場合、このフィールドに関する情報はfield_infoテーブルと定数プールに保存されます。
9. (methods_count とメソッド)
メソッド情報は、methods_info テーブルに格納されます。mehtods_count はテーブルの長さです。 Method_info テーブルには、クラスまたはインターフェイスで宣言されたメソッドのみが保存され、親クラスまたはインターフェイスから継承されたメソッドは保存されません。
メソッド名と記述子 (戻り値とパラメーターの型) は、Method_info テーブルに保存されます。抽象メソッドではない場合、スタックのサイズ (ローカル変数の保存に使用)、オペランド スタックの最大サイズ、キャッチされた例外リスト、メソッドのバイトコード、オプションの行番号、およびローカル変数テーブルが次のようになります。も保存されました。メソッドがいくつかのチェック例外をスローする場合、method_info にはチェック例外のリストも含まれます。
10. (attributes_count とattributes)
クラスファイルの最後は、属性の数とattributes_infoリストです。 Attribute_info テーブルは、属性の名前を格納する定数プール内の constant_utf8_info を指すいくつかのインデックスを格納します。 Java 仮想マシン仕様では、ソース コードと内部クラスという 2 種類の属性が定義されています。
上記は Java の入門: Java クラス ファイルの詳細な説明です。その他の関連記事については、PHP 中国語 Web サイト (www.php.cn) に注目してください。