2012-02-09 1 views
3

(ひどいタイトル、私が知っている)Javaには、既にシステムクラスローダーによって別のクラスによって読み込まれたクラスをロードする方法がありますか?

これを説明する最良の方法は、私はすでにされているクラスのインスタンスへの参照を持っているこれらのクラスによって、URLClassLoaderのから実行時にロードされるいくつかのクラスをロードする必要があるということですSystem ClassLoaderによってロードされ、他のいくつかの問題のために再読み込みできません。

また、クラスパス内のjarクラスをSystem ClassLoaderでロードできるように、コードを変更したいと思いますが、これを行うことはできませんでした。

答えて

3

いいえすべてのクラスローダーは、祖先としてブートストラップクラスローダーを持ち、クラスローダーにすでに定義されているクラスをロードしようとすると、祖先のバージョンが使用されます。これは、java.lang.Objectと他の組み込み関数が再定義されないようにすることを意図しています。 javadoc for ClassLoaderから

ClassLoaderクラスは、クラスおよびリソースを検索するための委譲モデルを使用しています。 ClassLoaderの各インスタンスには、関連付けられた親クラスローダがあります。 クラスまたはリソースの検索を要求された場合、ClassLoaderインスタンスは、クラスまたはリソース自体の検索を試みる前に、そのクラスまたはリソースの検索を親クラスローダーに委譲します。 "ブートストラップクラスローダ"と呼ばれる仮想マシンに組み込まれたクラスローダは、それ自体が親を持ちませんが、ClassLoaderインスタンスの親として機能します。

は、あなたはそれがfindClassによって呼び出されることなくdefineClassを公開するカスタムクラスローダを定義し、findClassで起こる委任を避けることができるかもしれないが、私はparent.findClass(className)が存在する場合、すべてのJVM上で意図したとおりに機能defineClass(className, bytes)に依存しないでしょう。

+0

ナッシングClassLoaderの特定の実装/サブクラスがこの動作を実際に実装するよう強制します。 – bmargulies

+0

@bmarguliesのように、私は 'resolveClass'がデリゲートを実装し、ロードされ、初期化された' Class'インスタンスのすべての生産のゲートキーパーです。 –

+0

resolveClassのjavadocに 'may'という単語があることに注目してください。 – bmargulies

1

はい、別のクラスローダーを定義してクラスをロードできます。 「

仕様を1として

実行時には、クラスやインタフェースがないだけでその名前ではなく、ペアによって決定されます。その完全修飾名とその定義クラスローダーような各クラスやインターフェイスが属しますクラスまたはインタフェースのランタイムパッケージは、パッケージ名およびクラスまたはインタフェースのクラスローダの定義によって決定されます。

0

はい。しかし、デフォルトの親クラスローダーはブートクラスローダーではなく、システムクラスローダーであるため、少し注意する必要があります。 java.net.URLClassLoader.newInstance(myURLs, null)を使用することをおすすめします。あなたがフラッシュしたい場合は、親クラスローダーをシステムクラスローダーから取得します。これには拡張クラスが含まれます。

(注、システムクラスは、システムクラスローダによってロードされないようにクラスパスが。今、ブートクラスパス(インストーラのための痛み)であるものを含まれている場合、それはJava2の前にさかのぼるので、専門用語が少しねじれたです。)