1-4-3ファイル構造


注:この記事は、学校の採用審査に関する一連の記事です。
詳細については、総合カタログを参照してください。 学校募集レビューカタログ

1.概要

Javaでは、JVMコードが理解できると呼ばれている字节码(つまり、拡張子.classのファイル)、それだけで仮想マシンのために、任意の特定のプロセッサに直面していません。Java言語は、インタープリター型言語の移植性を維持しながら、バイトコードを通じて従来のインタープリター型言語の実行効率が低いという問題をある程度解決しますしたがって、Javaプログラムは実行時により効率的であり、バイトコードは特定のマシン用ではないため、Javaプログラムは再コンパイルせずに多くの異なるオペレーティングシステムを搭載したコンピューターで実行できます。

Clojure(Lisp言語の方言)、Groovy、Scalaなどの言語はすべてJava仮想マシン上で実行されます。次の図は、さまざまな言語がさまざまなコンパイラーによって.classファイルにコンパイルされ、最終的にJava仮想マシンで実行されることを示しています。.classファイルのバイナリ形式は、WinHexを使用して表示できます

Java仮想マシン
.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 プラスチックリテラル
CONSTANT_Float_info 4 浮動小数点リテラル
CONSTANT_Long_info 長いリテラル
CONSTANT_Double_info 倍精度浮動小数点リテラル
CONSTANT_Class_info クラスまたはインターフェースへのシンボリック参照
CONSTANT_String_info 文字列型リテラル
CONSTANT_Fieldref_info フィールドへのシンボリック参照
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:スコープフィールド(publicprivateprotected修飾子)、インスタンス変数やクラス変数(あるstatic、(一過性改質剤)シリアル化することができる改質剤)は、変動(最終)、から強制かどうか可視(揮発性改質剤、メインメモリの読み取りと書き込み)。
  • name_index:フィールドの名前を示す定数プールへの参照。
  • descriptor_index:定数プールへの参照。フィールドとメソッドの記述子を示します。
  • attributes_count:フィールドには追加の属性もいくつかあります。attributes_countには属性の数が格納されます。
  • attributes [attributes_count]:特定の属性の特定のコンテンツを保存します。

上記の情報では、各修飾子はブール値であり、特定の修飾子があるかどうかにかかわらず、フラグビットを使用して表すのが適切です。フィールド名やフィールドのデータ型は固定されておらず、定数プールの定数を参照することでしか記述できません。

フィールドのaccess_flagsの値:

フィールドのaccess_flagsの値

2.7メソッドテーブルコレクション

    u2             methods_count;//Class 文件的方法的数量
    method_info    methods[methods_count];//一个类可以有个多个方法

method_countはメソッドの数を表し、method_infoはメソッドテーブルを表します。

Classファイルのストレージ形式でのメソッドの説明とフィールドの説明は、ほぼ完全に一致しています。メソッドテーブルの構造はフィールドテーブルの構造と同じで、アクセスマーク、名前インデックス、記述子インデックス、属性テーブルコレクションが順番に含まれます。

method_info(メソッドテーブル)構造:

メソッドテーブルの構造

メソッドテーブルのaccess_flag値:

メソッドテーブルのAccess_flag値

注:のでvolatile改質及びtransient改質剤は方法を変更することができない、アクセスフラグテーブルの方法は、これら2つの符号に対応するが、追加しないsynchronizednativeabstract及び他のキー修飾方法ので、複数のシンボルに対応するこれらのキーワードのために存在します。

2.8属性の収集

   u2             attributes_count;//此类的属性表中的属性数
   attribute_info attributes[attributes_count];//属性表集合

クラスファイル、フィールドテーブル、およびメソッドテーブルはすべて、特定のシーン固有の情報を記述するための独自の属性テーブルコレクションを運ぶことができます。Classファイル内の他のデータ項目で必要な順序、長さ、内容とは異なり、属性テーブルのコレクションは少し緩く、各属性テーブルに厳密な順序は必要ありません。実装されたコンパイラは独自の定義済み属性情報を属性テーブルに書き込むことができ、Java仮想マシンは実行時に認識しない属性を無視します。

元の記事を197件公開 賞賛20件 訪問7995件

おすすめ

転載: blog.csdn.net/Xjheroin/article/details/105702301