Javaクラスファイル

SectionsEdit

Javaクラスファイル構造には10の基本セクションがあります:

  • Magic Number: 0xCAFEBABE
  • Version of Class File Format: Classファイルのマイナーおよびメジャーバージョン
  • Constant Pool: クラスファイル内の定数。 クラスの定数プール
  • アクセスフラグ:例えば、クラスが抽象的か、静的か、など
  • このクラスです。 現在のクラスの名前
  • スーパークラス。 スーパークラスの名前
  • インターフェース。 クラス内のすべてのインターフェイス
  • フィールド。 クラス内の任意のフィールド
  • メソッド。 クラス内のすべてのメソッド
  • Attributes:

Magic NumberEdit

クラスファイルは、以下の4バイトのヘッダ(16進数)で識別されます。 CA FE BA BE (下表の最初の4つの項目)。 このマジック ナンバーの歴史は、James Gosling 氏が Palo Alto のレストランに言及して説明したものです:

「我々はよく St Michael’s Alley という場所にランチに行った。 地元の伝説によると、深く暗い過去に、グレイトフル・デッドが大成功する前に、そこで演奏していたそうです。 かなりファンキーな場所で、まさにGrateful Dead Kinda Placeだった。 ジェリーが亡くなった時には、小さな仏像のような神社まで建っていたそうです。 僕らがよく行っていた頃は、その場所をカフェ・デッドと呼んでいました。 いつの間にか、これがHEXナンバーであることに気がつきました。 ファイルフォーマットのコードを書き直しているときに、2つのマジックナンバーが必要になったんです:1つは永続オブジェクトファイル用、もう1つはクラス用です。 オブジェクトファイルのフォーマットにはCAFEDEADを使い、「CAFE」の後に続く4文字の16進数の単語をgrepしているうちに、BABEに行き当たり、それを使うことにしました。 そのため、CAFEBABEはクラス・ファイル・フォーマットになり、CAFEDEADは永続オブジェクト・フォーマットとなりました。 しかし、永続オブジェクト機能はなくなり、それとともに CAFEDEAD の使用もなくなり、最終的には RMI に置き換えられました。

General layoutEdit

クラスファイルは可変サイズのアイテムを含み、ファイルオフセット(またはポインタ)を埋め込まないため、通常は最初のバイトから終わりに向かって順にパースされます。

  • u1: 符号なし 8 ビット整数
  • u2: ビッグエンディアンバイトオーダーの符号なし 16 ビット整数
  • u4: ビッグエンディアンバイトオーダーの符号なし 32 ビット整数
  • table: ある型の可変長アイテムの配列である。 テーブル内の項目数は直前のカウント数(カウントはu2)で識別されるが、テーブルのバイトサイズは各項目を調べることによってのみ決定できる。

これらの基本型のいくつかは、文脈に応じて(文字列や浮動小数点数などの)より上位の値として再解釈される。

cpsize (variable)

22+cpsize +isize +fsize+msize

バイトオフセット サイズ タイプまたは値 説明
0 4バイト u1 =
0xCA hex
magic number (CAFEBABE) クラスファイルフォーマットに準拠したファイルであることを示すために使用
1 u1 =
0xFE hex
2 u1 =
0xBA hex
3 u1 =
0xBE hex
4 2 bytes u2 minorバージョンNo.
5
6 2 bytes u2 使用中のクラスファイルフォーマットのメジャーバージョン番号。

Java SE 17 = 61 (0x3D hex),
Java SE 16 = 60 (0x3C hex),
Java SE 15 = 59 (0x3B hex),
Java SE 14 = 58 (0x3A hex),
Java SE 13 = 57 (0x39 hex),
Java SE 12 = 56 (0x38 hex)です。
Java SE 11 = 55 (0x37 hex),
Java SE 10 = 54 (0x36 hex),
Java SE 9 = 53 (0x35 hex),
Java SE 8 = 52 (0x34 hex),
Java SE 7 = 51 (0x33 hex),
Java SE 6.0 = 50 (0x32 hex),
Java SE 5.0 (0x32 hex),
Java SE 6.0 = 49 (0x31 hex),
JDK 1.4 = 48 (0x30 hex),
JDK 1.3 = 47 (0x2F hex),
JDK 1.2 = 46 (0x2E hex),
JDK 1.1 = 45 (0x2D hex).です。
以前のバージョン番号の詳細は、The JavaTM Virtual Machine Specification 2nd edition

の脚注1を参照。

7
8 2バイト u2 定数プールカウント、次の定数プールテーブルにおけるエントリ数です。
9
10 table constant pool table, a array of variable-sized constant pool entries, containing literal numbers, string, and references to class or methods. インデックスは1から始まり、(定数プール数 – 1) 合計のエントリ数を含みます (注を参照)。
….
10+cpsize 2 bytes u2 access flags.NET。 ビットマスク
11+cpsize
12+cpsize 2 bytes u2 このクラスを特定するものです。 定数プールの “クラス “タイプのエントリへのインデックス
13+cpsize
14+cpsize 2 bytes u2 スーパークラスであると認識されます。 クラス “タイプのエントリへの定数プールへのインデックス
15+cpsize
16+cpsize 2 bytes u2 インタフェース数です。 5763>
17+cpsize
18+cpsize isize (variable) table インターフェーステーブルにおけるエントリ数です。 このクラスが実装するインターフェイスを記述する定数プールのインデックスの可変長配列
18+cpsize+isize 2 bytes u2 field count, 以下のフィールドテーブルのエントリ数
19+cpsize+isize
20+cpsize+isize fsize (variable) table field table, 可変長フィールド配列

各要素はhttps://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.5

で定義されたfield_info構造体である。..
20+cpsize+isize+fsize 2 bytes u2 method count.を参照。 以下のメソッドテーブルのエントリ数
21+cpsize+isize+fsize
22+cpsize+isize+fsize msize (variable) table method table, メソッドの可変長配列

各要素はhttps://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.6

で定義されたmethod_info構造体です。..
22+cpsize+isize+fsize+msize 2 bytes u2 attribute count.の略です。 以下の属性テーブルのエントリ数
23+cpsize+isize+fsize+msize
24+cpsize+isize+fsize+msize asize (variable) table attribute table.Of a attribute attribute table, 可変長の属性配列

各要素は、https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.7

で定義されたattribute_info構造体です。…

C言語ライクなプログラミング言語での表現編集

Cでは構造体に複数の可変長の配列はサポートしていないので、以下のコードはコンパイルできずデモとしてのみ機能することになります。

struct Class_File_Format { u4 magic_number; u2 minor_version; u2 major_version; u2 constant_pool_count; cp_info constant_pool; u2 access_flags; u2 this_class; u2 super_class; u2 interfaces_count; u2 interfaces; u2 fields_count; field_info fields; u2 methods_count; method_info methods; u2 attributes_count; attribute_info attributes;}

The constant poolEdit

The constant pool table is where the most of the literal constant values are stored. これには、あらゆる種類の数値、文字列、識別子名、クラスとメソッドへの参照、およびタイプ記述子のような値が含まれる。 定数プール テーブル内の特定の定数へのすべてのインデックスまたは参照は、16 ビット (u2 型) の数値で示され、インデックス値 1 はテーブル内の最初の定数を指します (インデックス値 0 は無効です)。 まず、テーブルのインデックスは0ではなく1から始まりますが、カウントは実際には最大インデックスに1を足したものと解釈されるべきです。 さらに、2 種類の定数 (longs と doubles) がテーブルの 2 つの連続したスロットを占めますが、2 番目のスロットは直接使用されることのないファントム・インデックスです。 このタグに続くバイト数とその解釈は、タグの値によって決まります。 有効な定数の型とそのタグの値は次のとおりである。

4 bytes

1 bytes

タグバイト 追加バイト 定数の説明 導入バージョン
1 2+xバイト
(変数)
UTF-8 (Unicode) 文字列.utf.utf.utf.utf.utf.utf.utf.utf.utf.utf.utf.を含む。 文字列の前に、直後に続く符号化文字列のバイト数(文字数とは異なる場合がある)を示す16ビットの数値(u2型)を付けたもの。 1.0.2
3 4 bytes Integer: ビッグエンディアン形式の符号付き32ビット2補数 1.0.2
4 Float: 32ビット単精度IEEE 754浮動小数点数 1.0.2
5 8 bytes Long: ビッグエンディアン形式の符号付き64ビット2の補数(定数プールテーブルの2スロットを使用) 1.0.2
6 8 bytes Double: 64ビット倍精度IEEE754浮動小数点数(定数プールテーブルで2スロット使用) 1.0.2
7 2 bytes Class reference: 完全修飾クラス名(内部フォーマット)を含む UTF-8 文字列への定数プール内のインデックス(ビッグエンディアン) 1.0.2
8 2 bytes String reference: UTF-8 string (big-endian too) 1.0.1 1.0 2 bytes String reference: 定数プールのインデックス。2
9 4 bytes Field reference: 定数プール内の2つのインデックス、最初のインデックスはクラス参照、次のインデックスは名前およびタイプ記述子を指します。 (ビッグエンディアン) 1.0.2
10 4 bytes Method reference: constant pool 内の 2 つのインデックス、最初のインデックスは Class 参照、次のインデックスは Name and Type ディスクリプタへのポインタを指します。 (ビッグエンディアン) 1.0.2
11 4 bytes インターフェイス メソッド リファレンス:定数プール内の 2 つのインデックス、最初のインデックスはクラス リファレンス、次のインデックスは Name and Type ディスクリプタへのポインティングです。 (ビッグエンディアン) 1.0.2
12 4 bytes Name and type descriptor: 2 つのインデックスがあり、最初のものは名前 (identifier) 、2番目は特別にコード化したタイプ デスクリプタである定数プール内の UTF-8 文字を指します。 1.0.2
15 3 bytes Method handle: この構造はメソッドハンドルを表すために使われ、1バイトのタイプディスクリプタと、定数プール内のインデックスから構成されています。 7
16 2 bytes Method type: この構造体はメソッドタイプを表すために使用され、定数プール内のインデックスで構成される。 7
17 4 bytes Dynamic: ブートストラップメソッドの呼び出しによって動的に生成された定数を指定するために使用される。 11
18 4 bytes InvokeDynamic: invokedynamic 命令が使用し、起動メソッド、動的呼び出し名、呼び出しの引数と戻り値の型、オプションとして起動メソッドの static 引数と呼ぶ追加定数の列が特定されます。 7
19 2 bytes Module: モジュールを識別するために使用されます。 9
20 2 bytes Package: モジュールによってエクスポートまたはオープンされたパッケージを識別するために使用されます。 9

整数型定数は integer と long の2種類のみです。

Javaのクラス名は、完全に修飾されている場合、伝統的に “java.lang.Object” のようにドットで区切られます。 しかし、低レベルのクラス参照定数内では、代わりに “java/lang/Object” のようにスラッシュを使用する内部形式が現れます。

Unicode 文字列は、「UTF-8 文字列」という名目にもかかわらず、類似しているものの、実際には Unicode 標準に従って符号化されていません。 2つの違いがあります(完全な議論についてはUTF-8を参照してください)。 第一は、コードポイントU+0000が、標準のシングルバイトのエンコーディング00ではなく、2バイトのシーケンスC0 80(16進数)としてエンコードされていることです。 第二の違いは、補足文字(U+10000以上のBMP外の文字)が、UTF-8で直接エンコードされるのではなく、UTF-16と同様のサロゲートペア構造でエンコードされる点です。 こ の場合、 2 個のサ ロ ゲー ト はそれぞれ UTF-8 で別々に符号化 さ れます。 た と えば U+1D11E は、 正 し い 4 バ イ ト の UTF-8 符号化である F0 9D 84 9E.

ではなく、 6 バ イ ト 列ED A0 B4 ED B4 9Eと して符号化 さ れま し た。

コメントを残す

メールアドレスが公開されることはありません。