なぜクラスローダーを使用するのですか?
Java言語では、プログラム操作中にクラスの読み込みが完了します。この戦略は、クラスのロード時にパフォーマンスオーバーヘッドをわずかに増加させますが、Javaアプリケーションに高度な柔軟性を提供します。例えば:
1.インターフェイス指向のアプリケーションを作成し、実装サブクラスを指定する前に実行されるまで待つことができます。
2。ユーザーはクラスローダーをカスタマイズして、プログラムが実行時にプログラムコードの一部としてネットワークまたは他の場所からバイナリストリームをロードできるようにすることができます。 (これは、Androidプラグイン、APKの動的インストール、更新の基礎です)
なぜクラスロードのプロセス全体を研究するのですか?
クラスロードメカニズム
JVMはクラスファイルをメモリにロードし、データをチェック、解析、および初期化し、最後にJVMが直接使用できるJavaタイプのプロセス全体を形成します。
負荷
クラスファイルのバイトコードコンテンツをメモリにロードし、静的データをメソッド領域のランタイムデータ構造に変換し、メソッドエリアクラスデータのアクセスポータルとして、ヒープ内のこのクラスを表すjava.lang.Classオブジェクトを生成します。このプロセスには、クラスローダーの参加が必要です。
リンク
JavaクラスのバイナリコードをJVMの実行状態に結合するプロセス
初期化
<clinit>()メソッドを実行するプロセスです。クラスコンストラクター<clinit>()メソッドは、コンパイラによって生成され、クラスのすべてのクラス変数の割り当てアクションと静的ステートメントブロック(静的ブロック)のステートメントのマージを自動的に収集します。<clinit>()メソッドがマルチスレッド環境で正しくロックされ、同期されることを保証します。例1:
public class demo01 {public static void main(string [] args){a a = new a(); System.out.println(a.width); }} class A {public static int width = 100; // static変数、静的フィールドfield static {system.out.println( "static初期化クラスA"); width = 300; } public a(){system.out.println( "クラスAのオブジェクトを作成"); }}分析:
説明:
スタック、ヒープ(作成されたオブジェクトの場所)、およびメモリ内のメソッド領域(実際には特別なヒープ)があります
1. JVMがDEMO01をロードするとき、メソッド領域に静的データ(クラス変数、クラスメソッド、コード...)を形成します。同時に、 java.lang.Classオブジェクト(反射オブジェクト)がヒープに形成され、DEMO01クラスを表します。オブジェクトを介して、クラスのバイナリ構造にアクセスできます。次に、変数クラスA情報をロードし、クラスAを表すヒープにオブジェクトAを形成します。
2。メインメソッドが実行されると、メインメソッドスタックフレームがスタックに形成され、1つのメソッドがスタックフレームに対応します。メインメソッドが他のメソッドを呼び出す場合、スタックに1つずつ押します。メインメソッドにはローカル変数AタイプAがあります。最初は、aの値はnullです。クラスAのコンストラクターは、newを通じて呼び出されます。 A()メソッドはスタックで生成され、Aオブジェクトはヒープで生成されます。次に、オブジェクトアドレスがスタック内のAに支払われます。この時点で、AにはAオブジェクトアドレスがあります。
3。A.WIDTHが呼び出されると、メソッドエリアデータが呼び出されます。
クラスが参照によってロードされると、クラスは1回しかロードされません
クラスの積極的な参照(クラスの初期化は間違いなく発生します)
java.lang.reflectパッケージメソッドを使用して、クラスに反射電話をかけますクラスへのパッシブ参照(クラスの初期化は発生しません)
例2:
public class demo01 {static {system.out.println( "static初期化Demo01"); } public static void main(string [] args)throws exception {system.out.println( "demo01のメインメソッド!"); System.out.println(system.getProperty( "Java.class.path")); // Active Reference // new a(); // System.out.println(a.width); // class.forname( "com.sinosoft.test.a"); // passive reference // System.out.println(a.max); // a [] as = new a [10]; System.out.println(b.width); // class bは読み込まれません}} class bはa {static {system.out.println( "static initialization b"); }} class A extends a_father {public static int width = 100; //静的変数、静的ドメインフィールドpublic static final int max = 100; static {system.out.println( "静的初期化クラスA"); width = 300; } public a(){system.out.println( "クラスAのオブジェクトを作成"); }} class a_fatherはobjectを拡張します{static {system.out.println( "static initialization a_father"); }}要約します
上記は、この記事のコンテンツ全体です。この記事の内容には、すべての人の研究や仕事に特定の参照値があることを願っています。ご質問がある場合は、メッセージを残してコミュニケーションをとることができます。 wulin.comへのご支援ありがとうございます。