1. 1つのコマンドが1つのプロセスに対応します。
Java プログラムを開始すると、つまり main メソッドを開始すると、プロセスがどれほど複雑であっても、Java 仮想マシン プロセスが開始されます。異なる JVM プロセスは相互に影響を与えません。 Java プログラムには、仮想マシンによって呼び出される main メソッドという入り口が 1 つしかないと言われるのはこのためです。 2 つの主要なメソッドは 2 つの JVM プロセスに対応し、2 つの異なるクラス ローダーを開始し、実際に異なるクラスを操作します。したがって、相互に影響を与えることはありません。
2. クラスの読み込み。
クラスを使用するとき、クラスがメモリにロードされていない場合、システムはロード、接続、初期化を通じてクラスを初期化します。
1. クラスのロード: クラスのクラス ファイルを JVM に読み込み、そのクラス オブジェクトを作成することを指します。
2. クラス接続: クラスのバイナリ データを JRE にマージすることを指します。これは 3 つの段階に分かれています:
a)、検証: ロードされたクラス ファイル データの正確性を確認します。
b). 準備: クラスの静的変数に記憶領域を割り当て、デフォルトの初期化を実行します。
c)、解析: クラスのバイナリ データ内のシンボル参照を直接参照に置き換えます。
3. 初期化: クラスの静的変数と静的初期化ブロックを初期化します。
(注: Final 型静的プロパティの場合、プロパティ値がコンパイル時に取得されている場合、プロパティを呼び出してもクラスは初期化されません。これは定数を使用することと同じであるためです。
ClassLoader( ) メソッド、クラスはロードされるだけで初期化されません)
3. クラスローダー。
クラスローダーは、.class ファイルをメモリにロードし、対応する java.lang.Class オブジェクトを生成する役割を果たします。クラスが JVM にロードされると、再度ロードされることはありません。
Java では、クラスは完全修飾クラス名 (つまり、パッケージ名 + クラス名) によって識別されます。
JVM では、クラスは完全修飾クラス名とクラスローダーによって識別されます。
JVM は実行時に 3 つのクラスローダー、つまり BootstrapClassLoader (ルート クラス ローダー)、ExtClassLoader (拡張クラス ローダー)、および AppClassLoader (システム クラス ローダー) を生成します。 UML の構造は次のとおりです。
このうち、BootstrapClassLoader は JRE のコア クラス ライブラリのロードを担当します。これは ClassLoader のサブクラスではなく、C++ で記述されているため、Java では見ることができません。 getParent(そのサブクラスの) メソッドを通じて null が返されます。 BootstrapClassLoader は、rt.jar や charsets.jar などの Java コア クラス ライブラリを JRE ターゲットにロードする役割を果たします。
図に示すように、ExtClassLoader と AppClassLoader は ClassLoader のサブクラスです。これらは API では見ることができません。rt.jar ファイル内にあります。完全修飾クラス名は、
sun.misc.Launcher$ExtClassLoader および sun.misc.Launcher$AppClassLoader です。
その中で、ExtClassLoader は JRE 拡張ディレクトリ ext に JAR パッケージをロードする役割を果たし、AppClassLoader はクラスパスパスの下にクラスパッケージをロードします。
テストは次のとおりです:
package com.stopTalking.crazy; public class TestClassLoader { public static void main(String[] args) { //获取当前线程的类装载器 ClassLoader loader = Thread.currentThread().getContextClassLoader(); //获取System类的类装载器 ClassLoader loader1 = System.class.getClassLoader(); //获取本类TestClassLoader的类装载器loader2 ClassLoader loader2 = TestClassLoader.class.getClassLoader(); //获取loader2的父类 ClassLoader loader3 = loader2.getParent(); //获取loader2的父类的父类 ClassLoader loader4 = loader3.getParent(); System.out.println(loader); System.out.println(loader1); System.out.println(loader2); System.out.println(loader3); System.out.println(loader4); } }
コンソール出力:
//当前线程类获取的类加载器是AppClassLoader sun.misc.Launcher$AppClassLoader@6b97fd //System类为根装载器加载,java中访问不到,所以为null null //本类的类加载器当然也是AppClassLoader sun.misc.Launcher$AppClassLoader@6b97fd sun.misc.Launcher$ExtClassLoader@1c78e57 null
Java クラス ローダーとクラス リフレクションの使用例関連記事の詳細については、PHP 中国語 Web サイトに注目してください。