ホームページ  >  記事  >  Java  >  インタビュアー: クラスロードプロセスについて教えてください (10 個の図)

インタビュアー: クラスロードプロセスについて教えてください (10 個の図)

Java后端技术全栈
Java后端技术全栈転載
2023-08-23 15:05:471572ブラウズ

##Loading

クラスを使用したいときは、次のことを行う必要があります。 ClassLoader を通じてクラスをメモリにロードします。

「クラスのロード フェーズでは、主に次の 3 つのことを完了します。」

  1. クラス全体を通じてクラスを取得します。 name
  2. のバイナリ ストリームは、クラスのバイナリ ストリームを解析し、メソッド領域
    のデータ構造の java.lang.Class クラスのインスタンスを作成します。
  3. . メソッド領域のこのクラスのアクセス エントリとして、このタイプを示します。
インタビュアー: クラスロードプロセスについて教えてください (10 個の図)

"のメソッド完全なクラス名によるクラスのバイナリ ストリームの取得はさまざまです。「

  1. zip パッケージから取得します。
  2. Get」ネットワークからのデータ
  3. ##動的プロキシ テクノロジなどのランタイム計算生成
  4. ....
  5. # "非配列型の読み込みフェーズの場合、Java 仮想マシンの組み込みクラス ローダーを使用して完了することも、ユーザー定義のクラス ローダーを使用して完了することもできます「

リンク

「リンクのこの段階は、主に検証、準備、分析の 3 つの部分に分かれています。」

検証

「検証フェーズの主な目的は、クラス ファイルの形式が正しく、実行時に仮想マシンのセキュリティが危険にさらされないことを確認してください。"

検証フェーズには多くのルールがありますが、大きく分けて次の 4 つがあります。ステージインタビュアー: クラスロードプロセスについて教えてください (10 個の図)「具体的な内容については、詳しくは説明しません。「Java仮想マシンを深く理解する」を参照してください。この記事は、概要を作成し、全体的なプロセスを把握することを目的としています。詳細については説明せずに、クラスのロードについて説明します。"

準備

「準備フェーズでは主にクラスの静的変数にメモリを割り当て、それらをデフォルト値に初期化します。」

一般的なデータ型のデフォルト値は次のとおりです

データ型 デフォルト値
バイト (バイト)0
short (short)0
int 0
long 0L
float 0.0f
double 0.0d
ブール値 false
char '\u0000'
参照 null

「クラス静的変数のフィールド属性テーブルに ConstantValue 属性が存在する場合、代入ステートメントは直接実行されます。」

では、どのような状況でフィールドが実行されるのかクラスの静的変数の属性テーブルは存在しますか? ConstantValue プロパティはどうですか?

  1. クラス静的変数は基本データ型であり、final によって変更されます
  2. クラス静的変数は文字列型であり、final によって変更されます、および量の形式のリテラル割り当てです。

クラス ファイルのバイトコードを簡単に表示するために、IDEA にプラグイン jclasslib バイトコード ビューアをダウンロードしました。これは非常に便利です。 。次のコードを使用して、バイトコードの形式で検証します

public class Person {

    private static int age = 10;
    private static final int length = 160;
    private static final String name = "name";
    private static final String loc = new String("loc");
}

インタビュアー: クラスロードプロセスについて教えてください (10 個の図)「したがって、長さと名前の属性には、準備段階で ConstantValue で指定された値が割り当てられます」

「それでは、age 属性と loc 属性はどの段階で割り当てられるのでしょうか? それは初期化段階であり、後で詳しく説明します。」 インタビュアー: クラスロードプロセスについて教えてください (10 個の図)

分析

「クラス、インターフェイス、フィールドの (定数プール内の) シンボリック参照を変換する」およびメソッドを直接参照に追加します。" シンボリック参照: 一連のシンボルを使用して、参照されるターゲットを説明します。 直接参照; ターゲットへの直接ポインタ

参加して次のようなクラスを作成してください

public class Student {

    private String name;
    private int age;

    public String getName() {
        return this.name;
    }
}

インタビュアー: クラスロードプロセスについて教えてください (10 個の図)フィールドを例にとると、名前と年齢に対応するオブジェクトは直接ポイントしません。メモリ アドレスの代わりに、文字列を使用して記述します (つまり、シンボリック参照)。解析段階では、これらの記述をターゲットを直接指すポインター (つまり、直接参照) に変換します。

初始化

「执行类静态成员变量赋值语句和静态代码块中的语句」

インタビュアー: クラスロードプロセスについて教えてください (10 個の図)

我们把上面的Student代码改成如下形式

public class Student {

    private String name;
    private int age = 10;
    private static int gender = 1;

    {
        System.out.println("构造代码块");
    }

    static {
        System.out.println("静态代码块");
    }

    public Student() {
        System.out.println("构造函数");
    }

    public String getName() {
        return this.name;
    }
}

可以看到字节码中包含了3个方法,getName方法我们知道,7e51f00a783d7eb8f68358439dee7daf和583d030be372af71281df966e84181a5方法里面执行了哪些逻辑?インタビュアー: クラスロードプロセスについて教えてください (10 個の図)从字节码的角度分析一波

「7e51f00a783d7eb8f68358439dee7daf方法」

インタビュアー: クラスロードプロセスについて教えてください (10 個の図)

从字节码可以看到7e51f00a783d7eb8f68358439dee7daf方法的主要逻辑为

  1. 调用父类的7e51f00a783d7eb8f68358439dee7daf方法
  2. 非静态成员变量赋值
  3. 执行构造代码块
  4. 执行构造函数

インタビュアー: クラスロードプロセスについて教えてください (10 個の図)「583d030be372af71281df966e84181a5方法」インタビュアー: クラスロードプロセスについて教えてください (10 個の図)从字节码可以看到583d030be372af71281df966e84181a5方法的主要逻辑为

  1. 静的変数の代入ステートメントを実行します。
  2. 静的コード ブロック内のステートメントを実行します。
  3. One注意すべき点 はい、 「Java 仮想マシンは、サブクラスの f7729255ed3b5adeaf95ded0aa3581a1 メソッドが実行される前に、親クラスの f7729255ed3b5adeaf95ded0aa3581a1 メソッドが実行されていることを確認します。」

# #「面接の質問によっては、静的コード ブロック、構築コード ブロック、コンストラクターの実行順序についてよく尋ねられるため、583d030be372af71281df966e84181a5 メソッドと 7e51f00a783d7eb8f68358439dee7daf メソッドの役割を理解することが依然として必要です。」

ここで結論を直接要約します。デモを書いて検証することができます

##「継承なしの実行シーケンス」

##静的コード ブロックと静的メンバー変数、実行順序は書き込み順序によって決まります (一度だけ実行されます)
  1. コード ブロックと非静的コード ブロックを構築しますメンバ変数の場合、実行順序は書き込み順序によって決まります
  2. Constructor
  3. ##「継承を伴う実行順序」

#親クラス static (静的コード ブロック、静的メンバー変数)、サブクラスの static (静的コード ブロック、静的メンバー変数) (1 回のみ実行されます)

  1. 親クラスの非静的 (コンストラクター) コード ブロック、非静的メンバー変数)、親クラスのコンストラクター
  2. 非静的サブクラス (構築コード ブロック、非静的メンバー変数)静的メンバー変数)、サブクラスのコンストラクター
  3. アンインストール

ガベージ コレクションは、ヒープだけでなくメソッド領域にも含まれます。ただし、メソッド領域の型データを再利用するための条件は比較的厳しいです。下図は一例です。メソッド領域の Simple クラスを再利用したいです。
  1. ヒープ内の Sample クラスとそのサブクラスがリサイクルされていることを確認する必要があります
  2. Sample クラスをロードする MyClassLoader がリサイクルされました
  3. Sample クラスに対応する Class オブジェクトがリサイクルされていますインタビュアー: クラスロードプロセスについて教えてください (10 個の図)

メソッド領域に型データのリサイクル条件が設定されていることがわかります。比較的厳密ですが、その影響は最小限であるため、一部のガベージ コレクターはメソッド領域の型データをリサイクルしません

#概要#クラスロード処理

インタビュアー: クラスロードプロセスについて教えてください (10 個の図)変数代入処理

インタビュアー: クラスロードプロセスについて教えてください (10 個の図)##

以上がインタビュアー: クラスロードプロセスについて教えてください (10 個の図)の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はJava后端技术全栈で複製されています。侵害がある場合は、admin@php.cn までご連絡ください。