基本的なJavaクラスの読み込みプロセスの詳細な紹介
基本プロセス:
- クラスの完全な資格のある名前に基づいてクラスを定義するバイナリバイトストリームをロードします。
- バイトストリームで表される静的ストレージ構造を、メソッド領域のランタイムデータ構造に変換します
- メモリ内のこのクラスを表すJava.lang.Classオブジェクトを生成し、このクラスのさまざまなデータアクセスポータルにアクセスする方法として使用します。
アレイクラス自体はクラスローダーを介して作成されるのではなく、Java仮想マシンによって直接作成され、アレイクラスの要素タイプはクラスローダーによってロードされます。
要素のタイプアレイクラス:すべての寸法を削除した後の配列のタイプ。
ファイル形式の確認:
- 0xcafebabyはマジックナンバーから始まります。
- 現在の仮想マシンは、プライマリバージョンおよびセカンダリバージョン番号を処理できます。
- 定数;
- インデックス実行タイプ。
- UTF8エンコードデータ型、
メタデータ検証:bytecode説明情報のセマンティック分析:
- 親クラスがあるかどうか。
- 親クラスが最終的な修正クラスを継承するかどうか。
- 抽出されていないクラスが、親クラスまたはインターフェイスで実装する必要がある方法を実装するかどうか。
- クラスのフィールドと方法の上書き、過負荷の矛盾。
バイトコード検証:セマンティックフローと制御フロー分析、およびメソッドボディ分析の検証を通じて、プログラムの合法性と正確性を決定します。
- シンボル参照検証:仮想マシンがシンボル参照を直接参照に変換すると、解析段階で、クラス自体の外側の情報の一致する検証を実行します。
- 対応するクラスが、象徴的な参照の文字によって記述された完全に適格な名前で見つけることができるかどうか。
- メソッドフィールドに一致する記述子がクラスにあるかどうか、および単純な名前で記述されたメソッドとフィールドがあるかどうかを指定します。
- 象徴的な参照におけるクラス、フィールド、および方法のアクセシビリティ。
準備:メソッド領域のクラス変数にメモリを割り当て、クラス変数の初期値を設定します。
- 通常、初期値はデータ型のゼロ値であり、最終的な変更値は対応する値に直接初期化されます。
- クラス変数は、インスタンス変数と区別される静的に変更された変数です。
分析:仮想マシンは、一定のプールのシンボリック参照を直接参照プロセスに置き換えます
cuntion_class_info、cuntion_fieldref_info、constant_methodref_info ..
- シンボル参照:記号のセットは、参照されるターゲットを記述します。あらゆる形態のリテラルを使用して、あいまいさなくターゲットを見つけることができます。仮想マシンメモリの実装とは関係ありません。また、参照ターゲットがロードされているかどうかに関係なく。
- 直接参照:ターゲットへの直接ポインター、オフセット、またはターゲットに間接的に配置されたハンドルは、仮想マシンによって実装されたメモリに関連しています。直接参照関連のターゲットオブジェクトはロードする必要があります。
- 。 。 。
初期化:クラス定義でJavaプログラムコードの実行を開始します。クラスコンストラクター<cinit>()メソッドを実行します。
<cinit>():
- コンパイラは、クラスファイルの定義順序に従ってクラスのクラス変数の割り当てアクションを自動的に収集し、静的ステートメントブロックのステートメントをマージします。静的ステートメントブロックは、前に定義された変数にのみアクセスできます。
- クラスコンストラクターとは異なり、親クラスのコンストラクターを示すように呼び出す必要はありません。仮想マシンは、サブクラスが実行される前に親クラス<cinit>()が実行されることを保証します。
- 親クラスの静的ステートメントブロックが最初に実行されます。
- <cinit>()はクラスやインターフェイスには必要ありません。変数割り当て操作または静的ステートメントブロックがない場合、生成されません。
- インターフェイスの<cinit>()は、親インターフェイスの<cinit>()を最初に実行する必要はなく、同じインターフェイス実装クラス<cinit>()は必要ありません。
- スレッドの安全性:仮想マシンは、<cinit>()がマルチスレッド環境で正しくロックされ、同期されることを保証します。 1つのスレッドのみが、初期化クラスの<cinit>()に同時にアクセスできます。
読んでくれてありがとう、私はそれがあなたを助けることができることを願っています。このサイトへのご支援ありがとうございます!