Oracleの公式Webサイトでは、クラスファイルが定義されています:https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html
ClassFile
構造
class
ファイルには、1つから構成され ClassFile
た構造:
ClassFile {
u4 magic;
u2 minor_version;
u2 major_version;
u2 constant_pool_count;
cp_info constant_pool[constant_pool_count-1];
u2 access_flags;
u2 this_class;
u2 super_class;
u2 interfaces_count;
u2 interfaces[interfaces_count];
u2 fields_count;
field_info fields[fields_count];
u2 methods_count;
method_info methods[methods_count];
u2 attributes_count;
attribute_info attributes[attributes_count];
}
マジック
この magic
アイテムは、class
ファイル形式を識別するマジックナンバーを提供し ます。それは価値があります 0xCAFEBABE
各クラスファイルの最初の4バイトはマジックナンバーと呼ばれ、その唯一の機能は、ファイルが仮想マシンで受け入れられるかどうかを判断することです。
多くのファイルストレージ標準では、ファイルヘッダーにマジックナンバーを格納するpictures gifやjpegなど、識別にマジックナンバーを使用しています。識別のために拡張子の代わりにマジックナンバーを使用することは、主にセキュリティ上の考慮事項に基づいています。これは、拡張子を名前変更やその他の方法で自由に変更できるためです。
minor_version、major_version
minor_version
と major_version
itemsの値は、 このclass
ファイルのマイナーバージョン番号とメジャーバージョン番号 です。同時に、メジャーバージョン番号とマイナーバージョン番号によってclass
ファイル形式のバージョンが決まり ます。場合 class
ファイルはメジャーバージョン番号Mとマイナーバージョン番号mを有し、我々は、そのバージョン示し class
、したがってmmのファイル形式を class
ファイル形式のバージョンは、例えば、1.5 <2.0 <2.1、辞書式に順序付けされてもよいです。
Java仮想マシンの実装はclass
、vがMi.0≤v≤Mj.mの連続した範囲にある場合にのみ、バージョンvのファイル形式をサポートでき ます。Java仮想マシンの実装が準拠するJavaSEプラットフォームのリリースレベルは、範囲を決定する責任があります。
JDKリリース1.0.2でのOracleのJava仮想マシンの実装は、class
ファイル形式バージョン45.0から45.3までをサポートし ます。JDKリリース1.1。*class
は、45.0から45.65535までの範囲のファイル形式バージョンをサポートし ます。k≥2の場合、JDKリリース1.kはclass
、45.0から44 + k.0までの範囲のファイル形式バージョンをサポートし ます。
constant_pool_count
constant_pool_count
アイテムの値は、 constant_pool
テーブルのエントリ数に1を加えたものに等しくなります 。 constant_pool
インデックスは、それがゼロよりも大きい場合に有効とみなさ未満され constant_pool_count
、型の定数のための例外 long
と double
に留意 §4.4.5。
constant_pool []
これ constant_pool
は、さまざまな文字列定数、クラス名とインターフェイス名、フィールド名、および 構造とそのサブ構造内で参照されるその他の定数を表す構造のテーブル(§4.4) ClassFile
です。各constant_pool
テーブルエントリの形式は 、最初の「タグ」バイトで示されます。
constant_pool
テーブルは1からインデックスされる constant_pool_count
1 - 。
access_flags
access_flags
アイテムの値は、 このクラスまたはインターフェイスへのアクセス許可とプロパティを示すために使用されるフラグのマスクです。各フラグの解釈は、設定されている場合、表4.1-Aに指定されています 。
表4.1-A。クラスアクセスとプロパティ修飾子
フラグ名 | 値 | 解釈 |
---|---|---|
ACC_PUBLIC |
0x0001 | 宣言された public ; パッケージの外部からアクセスできます。 |
ACC_FINAL |
0x0010 | 宣言された final ; サブクラスは許可されていません。 |
ACC_SUPER |
0x0020 | invokespecial 命令によって呼び出された場合、スーパークラスメソッドを特別に扱います 。 |
ACC_INTERFACE |
0x0200 | クラスではなく、インターフェースです。 |
ACC_ABSTRACT |
0x0400 | 宣言された abstract ; インスタンス化してはなりません。 |
ACC_SYNTHETIC |
0x1000 | 宣言された合成; ソースコードには存在しません。 |
ACC_ANNOTATION |
0x2000 | 注釈タイプとして宣言されています。 |
ACC_ENUM |
0x4000 | enum タイプとして宣言されてい ます。 |
インターフェイスは、ACC_INTERFACE
設定されているフラグによって区別さ れます。ACC_INTERFACE
フラグが設定されていない場合 、この class
ファイルはインターフェイスではなくクラスを定義します。
場合は ACC_INTERFACE
フラグが設定され、 ACC_ABSTRACT
フラグもセットでなければならない、と ACC_FINAL
、 ACC_SUPER
と、 ACC_ENUM
フラグセットが設定されていない必要があります。
ACC_INTERFACE
フラグが設定されていない場合は 、表4.1-Aの他のフラグのいずれかを 設定できます ACC_ANNOTATION
。ただし、そのような class
ファイルには、そのファイルACC_FINAL
と ACC_ABSTRACT
フラグの両方を設定してはなりません (JLS§8.1.1.2)。
ACC_SUPER
フラグによって発現させようとする二つの別のセマンティクスのかを示す invokespecial 命令(§ invokespecialはこのクラスまたはインタフェースに表示されている場合)。Java仮想マシンの命令セットへのコンパイラはACC_SUPER
フラグを設定する必要があり ます。Java SE 8以降では、Java仮想マシン は、 ファイル内のフラグの実際の値やファイルのバージョンに 関係なくACC_SUPER
、すべてのclass
ファイルに フラグが設定されている と見なし ます。class
class
この ACC_SUPER
フラグは、Javaプログラミング言語用に古いコンパイラーによってコンパイルされたコードとの下位互換性のために存在します。1.0.2より前のJDKリリースaccess_flags
では、現在表されているフラグにACC_SUPER
意味が割り当てられていないコンパイラが生成さ れ 、OracleのJava仮想マシン実装はフラグが設定されている場合はフラグを無視していました。
この ACC_SYNTHETIC
フラグは、このクラスまたはインターフェイスがコンパイラによって生成され、ソースコードに表示されないことを示します。
注釈タイプにはACC_ANNOTATION
フラグを設定する必要があります 。ACC_ANNOTATION
フラグが設定されている場合は、 フラグも設定する ACC_INTERFACE
必要があります。
この ACC_ENUM
フラグは、このクラスまたはそのスーパークラスが列挙型として宣言されていることを示します。
表4.1-Aでaccess_flags
割り当てられていない項目の すべてのビットは、 将来の使用のために予約されています。生成された ファイルではゼロに設定する 必要があり、Java仮想マシンの実装では無視する必要があります。class
このクラス
this_class
アイテムの値は 、constant_pool
テーブルへの有効なインデックスである必要があり ます。constant_pool
そのインデックスの エントリは、この ファイルで定義されたクラスまたはインターフェイスを表すCONSTANT_Class_info
構造(§4.4.1) である必要があり class
ます。
super_class
クラスの場合、super_class
アイテムの値は ゼロであるか、constant_pool
テーブルへの有効なインデックスである必要があり ます。super_class
アイテムの値 がゼロ以外の場合、constant_pool
そのインデックスの エントリは、CONSTANT_Class_info
このclass
ファイルで定義されているクラスの直接のスーパークラスを表す構造体である 必要があり ます。直接スーパークラスもそのスーパークラスも 、その 構造体の項目に ACC_FINAL
フラグを設定する ことはできません 。access_flags
ClassFile
super_class
アイテムの値 がゼロの場合、この class
ファイルはクラスを表す必要があり Object
ます。これは、直接のスーパークラスがない唯一のクラスまたはインターフェイスです。
インターフェイスの場合、super_class
アイテムの値は 常にconstant_pool
テーブルへの有効なインデックスである必要があり ます。constant_pool
そのインデックスの エントリはCONSTANT_Class_info
、クラスを表す構造体 である必要があります Object
。
interfaces_count
interfaces_count
itemの値は、 このクラスまたはインターフェイスタイプの直接スーパーインターフェイスの数を示します。
interfaces []
interfaces
配列の各値は 、constant_pool
テーブルへの有効なインデックスである必要があり ます。 constant_pool
各値のエントリ 、0≤ I < 、でなければならない タイプのソースに与えられた左から右への順で、このクラスまたはインタフェースタイプの直接スーパあるインタフェースを表す構造。interfaces[i]
interfaces_count
CONSTANT_Class_info
fields_count
fields_count
アイテムの値は field_info
、fields
テーブル内の構造 の数を 示します。 field_info
構造はこのクラスまたはインタフェースの種類によって宣言されたすべてのフィールド、クラス変数とインスタンス変数の両方を表します。
田畑[]
fields
テーブルの各値は、 このクラスまたはインターフェイスのフィールドの完全な説明を提供するfield_info
構造(§4.5)である必要があり ます。この fields
テーブルには、このクラスまたはインターフェイスによって宣言されたフィールドのみが含まれています。スーパークラスまたはスーパーインターフェースから継承されたフィールドを表すアイテムは含まれません。
methods_count
methods_count
アイテムの値は method_info
、methods
テーブル内の構造 の数を 示します。
メソッド[]
methods
テーブルの各値は、 このクラスまたはインターフェイスのメソッドの完全な説明を提供するmethod_info
構造体(§4.6)である必要があり ます。 構造体 の 項目に フラグACC_NATIVE
と ACC_ABSTRACT
フラグのどちらも設定されて いない場合 、メソッドを実装するJava仮想マシンの命令も提供されます。access_flags
method_info
method_info
構造は、すべてのメソッドがインスタンスメソッド、クラスメソッド、インスタンスの初期化方法(含む、このクラスまたはインタフェースタイプによって宣言表し§2.9)、及び任意のクラスまたはインタフェースの初期化方法(§2.9)。この methods
テーブルには、スーパークラスまたはスーパーインターフェイスから継承されたメソッドを表す項目は含まれていません。
attributes_count
attributes_count
アイテムの値は、 attributes
このクラスのテーブル内の属性の数を示します 。
属性[]
attributes
テーブルの各値は attribute_info
構造体である必要があります (§4.7)。
構造のattributes
表に ClassFile
表示されるようにこの仕様で定義されている属性 を 表4.7-Cに示します。
構造のattributes
テーブル に表示されるように定義された属性に関する規則 ClassFile
は、§4.7に記載されてい ます。
構造のattributes
テーブル 内の事前定義されていない属性に関する規則 ClassFile
は、§4.7.1に記載されてい ます。