ホームページ >Java >&#&チュートリアル >Javaクラスローダーとクラスリフレクションの使用例

Javaクラスローダーとクラスリフレクションの使用例

高洛峰
高洛峰オリジナル
2017-01-13 09:22:331528ブラウズ

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 の構造は次のとおりです。

Javaクラスローダーとクラスリフレクションの使用例

このうち、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 サイトに注目してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。