30

Systemクラスローダーを次のようにオーバーライドできることがわかっています。

java -Djava.system.class.loader=com.test.MyClassLoader xxx

では、com.test.MyClassLoaderそれ自体がクラスなので、誰がロードするのでしょうか。

この「メタ」クラスローダーのクラスファイルを取得するにはどうすればよいですか?

4

4 に答える 4

26

Bootstrap classloaderすべての親でありclassloaders、JRE の lib ディレクトリ (rt.jar および i18n.jar) に標準の JDK クラスをロードします。すべての java.* クラスは、この によってロードされますclassloader

Extensions ClassloaderBootstrap クラスローダの直接の子です。このクラスローダは、JRE の lib\ext ディレクトリにクラスをロードします。

System-Classpath classloaderExtensions クラスローダーの直接の子です。CLASSPATH環境変数で指定されたクラスとjarをロードします

「java.system.class.loader」プロパティを使用して、カスタム クラス ローダーの挿入を試みることができます ( ClassLoader#getSystemClassLoaderを参照)。

Default System class loaderMyClassLoader インスタンスの親であり、

于 2012-07-09T13:38:21.117 に答える
21

のJavadocからClassLoader.getSystemClassLoader

このメソッドが最初に呼び出されたときにシステム プロパティ「java.system.class.loader」が定義されている場合、そのプロパティの値は、システム クラス ローダーとして返されるクラスの名前と見なされます。クラスは、デフォルトのシステム クラス ローダーを使用してロードされ、委譲の親として使用される ClassLoader 型の 1 つのパラメーターを受け取るパブリック コンストラクターを定義する必要があります。

デフォルトのシステム クラス ローダー自体は、JVM 実装に固有です。

于 2012-07-09T12:38:50.403 に答える
9

名前:

§ ..そのプロパティの値は、システム クラス ローダーとして返されるクラスの名前と見なされます。クラスは、デフォルトのシステム クラス ローダーを使用してロードされます。

..したがって、クラスローダがシステム クラス ローダとして X を置き換える場合、クラスローダの親はデフォルトのシステム クラス ローダである X になります。

(X は のような型ですsun.misc.Launcher$AppClassLoader。)

詳細については、docs.oracle.com - How the Java Launcher Finds Classesを参照してください。

Java ランチャーである java は、Java 仮想マシンを開始します。仮想マシンは、次の順序でクラスを検索してロードします。

ブートストラップ クラス- Java プラットフォームを構成するクラス。rt.jar 内のクラスやその他のいくつかの重要な jar ファイルが含まれます。

拡張クラス- Java 拡張メカニズムを使用するクラス。これらは、extensions ディレクトリにある .jar ファイルとしてバンドルされています。

ユーザー クラス- 拡張メカニズムを利用しない、開発者およびサード パーティによって定義されたクラス。コマンド ラインで -classpath オプションを使用するか、CLASSPATH 環境変数を使用して、これらのクラスの場所を特定します。

Tsmr:

X が実際に の親であることを証明できますClassloader

/** run with -Djava.system.class.loader=MyCL to use this classloader */
public class MyCL extends ClassLoader {
    public MyCL(ClassLoader parent) { // this constructor must be public, else IllegalAccessException
        super(parent);
    }
}

これは私たちのメインコードです:

public class Main {
    public static void main(String args[]) {
        System.out.println("getSystemClassLoader(): " + ClassLoader.getSystemClassLoader());

        ClassLoader cl = MyCL.class.getClassLoader();
        System.out.println("Classloader of MyCL: " + cl);

        Class type_of_cl = cl.getClass();
        System.out.println("..and its type: " + type_of_cl);

        ClassLoader cl_of_cl = class_of_cl.getClassLoader();
        System.out.println("Classloader of (Classloader of MyCL): " + cl_of_cl);
    }
}

これは、コマンドを使用して実行したときの (私のシステムでの) 出力ですjava -Djava.system.class.loader=MyCL Main(cf. Eclipse run config ):

getSystemClassLoader(): MyCL@1888759 MyCL
のクラスローダー: sun.misc.Launcher$AppClassLoader@7fdcde ..
およびそのタイプ: クラス sun.misc.Launcher$AppClassLoader クラスローダー
(MyCL のクラスローダー): null

MyCLのクラスローダはsun.misc.Launcher$AppClassLoader、デフォルトのシステム クラスローダであることがわかります。

(上記のOracleの他の引用に見られる言語によると、デフォルトのシステムクラスローダーは「ユーザークラス」のクラスローダーとも呼ばれます。同じものに2つの名前を考え出すためにOracleをねじ込みます。)

于 2014-08-24T23:59:43.377 に答える