A、クラスファイルの構造
JDKのバージョン番号は、言語の他の側面に対する変化を14に達している、APIとJava技術システムは、クラスファイルの構造は、比較的安定した状態にあった、主な構造と小さなクラスファイルのバイトコード命令のセマンティクスの数変化がありました。
クラス・ファイルは、各データ項目に基づいて、バイト単位で8ビットのバイナリ・ストリームのセットは、ほぼ全てのクラスに格納されているファイル全体の内容を作るれ、任意の中間セパレータを追加することなく、クラスファイル内の正確な順序にコンパクトに配置されていますプログラムを実行するために必要なデータは、隙間がありません。
符号なしとテーブル:データを保存するために、Java仮想マシン仕様、Cのような疑似言語構造のクラスファイルフォーマット構造の下では、そのようなダミー構造は、データの2種類のみです。
符号なし:U1、U2、U4、1つのバイトを表す符号なしの数にU8、2バイト、4バイト、8バイト、符号なしの数の数字を記述するために使用することができ、参照インデックスで、値または文字列値の数は、UTF-8エンコーディングに従って構成される。
表:終了「_info」非テーブルの複数のシンボルの数、またはデータ項目の複合などの他のデータ・タイプ、すべてのテーブルが習慣的であるが、階層の複合データ構造を記述するために使用される本質的にファイル全体であるクラスでありますテーブル。
以下は、クラスファイル形式であります:
タイプ | 名前 | 数量 | 説明 |
---|---|---|---|
U4 | マジック | 1 | これは、ファイルは、仮想マシン、クラスファイルとして受け入れることができるかどうかを示します |
U2 | minor_version | 1 | マイナーバージョン番号 |
U2 | major_version | 1 | 45の開始からのメジャーバージョン番号は、Javaのバージョン番号 |
U2 | constant_pool_count | 1 | 定数プールカウント値容量 |
cp_info | constant_pool | constant_pool_count-1 | リテラルとシンボリック参照(下記の定義を参照してください):定数プールは、クラスファイルリソース倉庫、二つのカテゴリ定数の主記憶装置であります |
U2 | access_flags | 1 | 情報へのアクセスのクラス/インターフェースの階層を識別する、など:このクラスは、最終的かどうかのように、pubilcかどうか、クラスまたはインタフェースであります |
U2 | このクラス | 1 | クラスの完全修飾名を決定するためのクラスインデックス |
U2 | super_class | 1 | クラスの親クラスの完全修飾名を決定するための親のインデックス |
U2 | interfaces_count | 1 | インターフェースの数は、インデックスセット内に実装しました |
U2 | インターフェース | interfaces_count | このクラスが実装するインタフェースを記述するために使用され |
U2 | fields_count | 1 | フィールドの数 |
field_info | 田畑 | fields_count | 説明インターフェイスまたは変数は、クラスのインスタンス変数とクラス変数段階を含む、クラス内で宣言しました |
U2 | methods_count | 1 | 定量的な方法 |
method_info | 方法 | methods_count | この方法は、インターフェースを記載し、またはクラス内で宣言され、インスタンス、及びメソッドは、クラスレベルのスケールの方法を含みます |
U2 | attributes_count | 1 | プロパティの数 |
attribute_info | 属性 | attributes_count | 説明フィールド/メソッドテーブルの付加情報、例えば特定コードメモリのコードとして、定数を格納すると一定値等 |
リテラルは、最終など一定の値として宣言されたJava言語のテキスト文字列を指します。シンボリック参照は、以下の3つの定数を含む、コンパイラの理論的側面の概念に属します。
- クラスやインタフェースの完全修飾名
- シンボル名または説明欄
- 方法識別子の名前または説明
二、クラスファイルのバイトコード
public class TestClass {
private int m;
public int inc() {
return m + 1;
}
}
クラスファイルのバイトコードを解析するためのコンテンツ-verboseパラメータJAVA_HOME / binに/てjavapツールを出力することにより、我々TestClass.classファイル。
javap -verbose TestClass
Classfile /D:/JMCui/jvm-demo/demo/target/classes/org/jvm/demo/chapter6/TestClass.class
Last modified 2020-4-1; size 397 bytes
MD5 checksum 291f52e2b746bf6c338ece68fdf3dc08
Compiled from "TestClass.java"
public class org.jvm.demo.chapter6.TestClass
minor version: 0
major version: 52
flags: ACC_PUBLIC, ACC_SUPER
Constant :
#1 = Methodref #4.#18 // java/lang/Object."<init>":()V
#2 = Fieldref #3.#19 // org/jvm/demo/chapter6/TestClass.m:I
#3 = Class #20 // org/jvm/demo/chapter6/TestClass
#4 = Class #21 // java/lang/Object
#5 = Utf8 m
#6 = Utf8 I
#7 = Utf8 <init>
#8 = Utf8 ()V
#9 = Utf8 Code
#10 = Utf8 LineNumberTable
#11 = Utf8 LocalVariableTable
#12 = Utf8 this
#13 = Utf8 Lorg/jvm/demo/chapter6/TestClass;
#14 = Utf8 inc
#15 = Utf8 ()I
#16 = Utf8 SourceFile
#17 = Utf8 TestClass.java
#18 = NameAndType #7:#8 // "<init>":()V
#19 = NameAndType #5:#6 // m:I
#20 = Utf8 org/jvm/demo/chapter6/TestClass
#21 = Utf8 java/lang/Object
{
public org.jvm.demo.chapter6.TestClass();
descriptor: ()V
flags: ACC_PUBLIC
Code:
stack=1, locals=1, args_size=1
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
LineNumberTable:
line 7: 0
LocalVariableTable:
Start Length Slot Name Signature
0 5 0 this Lorg/jvm/demo/chapter6/TestClass;
public int inc();
descriptor: ()I
flags: ACC_PUBLIC
Code:
stack=2, locals=1, args_size=1
0: aload_0
1: getfield #2 // Field m:I
4: iconst_1
5: iadd
6: ireturn
LineNumberTable:
line 12: 0
LocalVariableTable:
Start Length Slot Name Signature
0 7 0 this Lorg/jvm/demo/chapter6/TestClass;
}
SourceFile: "TestClass.java"
上記のマイナーバージョン、メジャーバージョン、フラグ、定数の意味がよりよく理解されています。
コード情報は、Javaプログラムがコードにある場合、このプロパティは、クラスファイルの最も重要な特性である(コード、どの方法ボディJavaコード)とメタデータ(メタデータ、クラス、フィールド、メソッド、および定義されている他の情報を含みます)二つの部分、全体のクラスファイル、コード記述コード属性は、他のすべてのデータ項目は、メタデータを記述するために使用されています。
スタック、地元の人々についてのコンテンツコードの属性、スタックスタックオペランドは、ローカル変数テーブルのストレージスペースが属する地元の人々について表し、単位は、使用するメモリの最小単位に割り当てられたスロット、スロットマシンの仮想ローカル変数です。
args_sizeは、パラメータの数は、少なくともメソッドのオブジェクトのローカル変数ローカル変数テーブルの例の現在のインスタンスへのポインタが存在することになるので、上記の理由は、args_size 1であり、ローカル変数テーブルはまた別に、第1のビットスロットが設定されている表しますオブジェクト・インスタンスへの参照を格納します。
LineNumberTableは行番号(オフセットバイトコード)バイトコードとの関係を対応するJavaソースコードの行番号を記述するために使用されます。
LocalVariableTableは、 Javaソースコードで定義されたローカル変数テーブル変数のスタックフレームの変数間の関係を記述するために使用されます。LocalVariableTypeTable特性シグネチャ(署名)情報を記録するための一般的なタイプ。
SOURCEFILEは、クラスファイルの生成されたソースコードのファイル名を記録します。
aload_0、invokespecial、返すこれらの焦点はバイトコード命令に、バイトコード命令に関連し、この資料に記載されていない、と他の属性情報を読み取ることができ属する「Java仮想マシン仕様。」