記事ディレクトリ
注:この記事は、学校の採用審査に関する一連の記事です。
詳細については、総合カタログを参照してください。 学校募集レビューカタログ
1.概要
Javaでは、JVMコードが理解できると呼ばれている字节码
(つまり、拡張子.class
のファイル)、それだけで仮想マシンのために、任意の特定のプロセッサに直面していません。Java言語は、インタープリター型言語の移植性を維持しながら、バイトコードを通じて従来のインタープリター型言語の実行効率が低いという問題をある程度解決します。したがって、Javaプログラムは実行時により効率的であり、バイトコードは特定のマシン用ではないため、Javaプログラムは再コンパイルせずに多くの異なるオペレーティングシステムを搭載したコンピューターで実行できます。
Clojure(Lisp言語の方言)、Groovy、Scalaなどの言語はすべてJava仮想マシン上で実行されます。次の図は、さまざまな言語がさまざまなコンパイラーによって.class
ファイルにコンパイルされ、最終的にJava仮想マシンで実行されることを示しています。.class
ファイルのバイナリ形式は、WinHexを使用して表示できます。
.classファイルは、Java仮想マシンのさまざまな言語間の重要な橋渡しであり、Javaクロスプラットフォームをサポートするための非常に重要な理由でもあると言えます。
2. Classファイルの全体的な構造
Java Virtual Machine仕様によれば、クラスファイルは単一のClassFile構造で構成されています。
ClassFile {
u4 magic; //Class 文件的标志
u2 minor_version;//Class 的小版本号
u2 major_version;//Class 的大版本号
u2 constant_pool_count;//常量池的数量
cp_info constant_pool[constant_pool_count-1];//常量池
u2 access_flags;//Class 的访问标记
u2 this_class;//当前类
u2 super_class;//父类
u2 interfaces_count;//接口
u2 interfaces[interfaces_count];//一个类可以实现多个接口
u2 fields_count;//Class 文件的字段属性
field_info fields[fields_count];//一个类会可以有个字段
u2 methods_count;//Class 文件的方法数量
method_info methods[methods_count];//一个类可以有个多个方法
u2 attributes_count;//此类的属性表中的属性数
attribute_info attributes[attributes_count];//属性表集合
}
以下では、Classファイル構造に関連するいくつかのコンポーネントについて詳しく説明します。
クラスファイルのバイトコード構造編成の概略図(以前はインターネットに保存されていましたが、非常に良いです。元のソースは不明です):
2.1 魔数
u4 magic; //Class 文件的标志
各クラスファイルの最初の4バイトはマジックナンバーと呼ばれ、その唯一の目的は、このファイルが仮想マシンが受信できるクラスファイルかどうかを判別することです。
プログラマーは、固定されたファイルタイプやその他の特別な意味を示すために、いくつかの特別な番号を使用することを好みます。
2.2クラスファイルのバージョン
u2 minor_version;//Class 的小版本号
u2 major_version;//Class 的大版本号
マジックナンバーに続く4バイトには、Classファイルのバージョン番号が格納されています。5番目と6番目はマイナーバージョン番号、7番目と8番目はメジャーバージョン番号です。
高レベルJava仮想マシンは低レベルコンパイラによって生成されたクラスファイルを実行できますが、低レベルJava仮想マシンは高レベルコンパイラによって生成されたクラスファイルを実行できません。したがって、実際に開発するときは、開発のJDKバージョンと本番環境のJDKバージョンが一致していることを確認する必要があります。
2.3定数プール
u2 constant_pool_count;//常量池的数量
cp_info constant_pool[constant_pool_count-1];//常量池
メジャーバージョン番号とマイナーバージョン番号が定数プールになった直後、定数プールの数はconstant_pool_count-1です(定数プールカウンターは1からカウントされ、0番目の定数を空にすることについて特別な考慮事項があります。インデックス値0は "定数プール項目を参照しないでください ")。
**定数プールには、主に2つの主要な定数、リテラルとシンボル参照が格納されます。**リテラルは、テキスト文字列、finalとして宣言された定数値など、Java言語の定数の概念に近いものです。シンボリック参照は、コンパイルの原則の概念に属しています。次の3つのタイプの定数が含まれています。
- クラスとインターフェースの完全修飾名
- フィールド名と記述子
- メソッド名と記述子
定数プールの各定数はテーブルです。これらの14種類のテーブルには共通の機能があります。最初の最初のビットは、定数のタイプを識別するu1タイプのフラグ-タグであり、この定数が属する定数を表します。タイプ。
タイプ | タグ付け | 説明文 |
---|---|---|
CONSTANT_utf8_info | 1 | UTF-8エンコードされた文字列 |
CONSTANT_Integer_info | 3 | プラスチックリテラル |
CONSTANT_Float_info | 4 | 浮動小数点リテラル |
CONSTANT_Long_info | 5 | 長いリテラル |
CONSTANT_Double_info | 6 | 倍精度浮動小数点リテラル |
CONSTANT_Class_info | 7 | クラスまたはインターフェースへのシンボリック参照 |
CONSTANT_String_info | 8 | 文字列型リテラル |
CONSTANT_Fieldref_info | 9 | フィールドへのシンボリック参照 |
CONSTANT_Methodref_info | 10 | クラス内のメソッドへのシンボリック参照 |
CONSTANT_InterfaceMethodref_info | 11 | インターフェイスのメソッドへのシンボリック参照 |
CONSTANT_NameAndType_info | 12 | フィールドまたはメソッドへのシンボリック参照 |
CONSTANT_MothodType_info | 16 | フラグメソッドタイプ |
CONSTANT_MethodHandle_info | 15 | メソッドハンドル |
CONSTANT_InvokeDynamic_info | 18 | 動的メソッド呼び出しポイントを表します |
.class
ファイルは、javap -v class类名
コマンド(javap -v class类名-> temp.txt
:temp.txtファイルに結果を出力する)を使用して、定数プール内の情報を確認できます。
2.4アクセスロゴ
定数プールの終了後、次の2バイトはアクセスフラグを表します。このフラグは、クラスまたはインターフェイスレベルのアクセス情報を識別するために使用されます。このクラスは、クラスまたはインターフェイスであるか、パブリックであるか抽象であるか、およびクラスであるかどうかを示します。最終宣言等された場合
クラスアクセスと属性修飾子:
Employeeクラスを定義します
package top.snailclimb.bean;
public class Employee {
...
}
javap -v class类名
命令を通してクラスのアクセスフラグを見てください。
2.5現在のクラスインデックス、親クラスインデックス、およびインターフェイスインデックスコレクション
u2 this_class;//当前类
u2 super_class;//父类
u2 interfaces_count;//接口
u2 interfaces[interfaces_count];//一个类可以实现多个接口
クラスインデックスは、このクラスの完全修飾名を決定するために使用され、親クラスインデックスは、このクラスの親クラスの完全修飾名を決定するために使用されます。Java言語の単一継承のため、java.lang.Object以外の親クラスインデックスは1つだけですすべてのJavaクラスには親クラスがあるため、java.lang.Objectを除き、すべてのJavaクラスの親クラスインデックスは0ではありません。
インターフェースインデックスセットは、このクラスが実装するインターフェースを説明するために使用されます。これらの実装されたインターフェースは、(クラス自体がインターフェースの場合)インターフェースの順序で左から右にインターフェースインデックスセットに配置されます。
2.6フィールドテーブル
u2 fields_count;//Class 文件的字段的个数
field_info fields[fields_count];//一个类会可以有个字段
フィールド情報(フィールド情報)は、インターフェースまたはクラスで宣言された変数を記述するために使用されます。フィールドには、クラスレベル変数とインスタンス変数が含まれますが、メソッド内で宣言されたローカル変数は含まれません。
フィールド情報の構造(フィールドテーブル):
- access_flags:スコープフィールド(
public
、private
、protected
修飾子)、インスタンス変数やクラス変数(あるstatic
、(一過性改質剤)シリアル化することができる改質剤)は、変動(最終)、から強制かどうか可視(揮発性改質剤、メインメモリの読み取りと書き込み)。 - name_index:フィールドの名前を示す定数プールへの参照。
- descriptor_index:定数プールへの参照。フィールドとメソッドの記述子を示します。
- attributes_count:フィールドには追加の属性もいくつかあります。attributes_countには属性の数が格納されます。
- attributes [attributes_count]:特定の属性の特定のコンテンツを保存します。
上記の情報では、各修飾子はブール値であり、特定の修飾子があるかどうかにかかわらず、フラグビットを使用して表すのが適切です。フィールド名やフィールドのデータ型は固定されておらず、定数プールの定数を参照することでしか記述できません。
フィールドのaccess_flagsの値:
2.7メソッドテーブルコレクション
u2 methods_count;//Class 文件的方法的数量
method_info methods[methods_count];//一个类可以有个多个方法
method_countはメソッドの数を表し、method_infoはメソッドテーブルを表します。
Classファイルのストレージ形式でのメソッドの説明とフィールドの説明は、ほぼ完全に一致しています。メソッドテーブルの構造はフィールドテーブルの構造と同じで、アクセスマーク、名前インデックス、記述子インデックス、属性テーブルコレクションが順番に含まれます。
method_info(メソッドテーブル)構造:
メソッドテーブルのaccess_flag値:
注:のでvolatile
改質及びtransient
改質剤は方法を変更することができない、アクセスフラグテーブルの方法は、これら2つの符号に対応するが、追加しないsynchronized
、native
、abstract
及び他のキー修飾方法ので、複数のシンボルに対応するこれらのキーワードのために存在します。
2.8属性の収集
u2 attributes_count;//此类的属性表中的属性数
attribute_info attributes[attributes_count];//属性表集合
クラスファイル、フィールドテーブル、およびメソッドテーブルはすべて、特定のシーン固有の情報を記述するための独自の属性テーブルコレクションを運ぶことができます。Classファイル内の他のデータ項目で必要な順序、長さ、内容とは異なり、属性テーブルのコレクションは少し緩く、各属性テーブルに厳密な順序は必要ありません。実装されたコンパイラは独自の定義済み属性情報を属性テーブルに書き込むことができ、Java仮想マシンは実行時に認識しない属性を無視します。