3

(ひどいタイトル、私は知っています)

これを説明する最善の方法は、実行時に URLClassLoader からロードされるいくつかのクラスをロードする必要があるということです。これらのクラスは、システム ClassLoader によってすでにロードされているクラスのインスタンスへの参照を持ち、再ロードできないためです。他のいくつかの問題の。

また、System ClassLoader を使用してクラス パス内の jar からクラスをロードできるようにコードを変更したいと考えていますが、それはできませんでした。

4

3 に答える 3

3

いいえ。すべてのクラスローダーには祖先としてブートストラップクラスローダーがあり、クラスローダーですでに定義されているクラスをロードしようとすると、祖先のバージョンが使用されるだけです。java.lang.Objectこれは、その他の組み込み関数が再定義されるのを防ぐための意図的なものです。

javadocからClassLoader

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

defineClass呼び出されることなく公開するカスタムクラスローダーを定義し、findClassで発生する委任を回避できる場合がありますが、存在する場合はすべてのJVMで意図したとおりに機能することにfindClass依存しません。defineClass(className, bytes)parent.findClass(className)

于 2012-02-09T23:29:08.557 に答える
1

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

仕様による

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

于 2012-02-09T23:30:35.500 に答える
1

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

(注: 用語は少しねじれています。クラスパスに現在の bootclasspath が含まれていた Java2 より前にさかのぼるためです (インストーラーにとっては苦痛です)。そのため、システム クラスはシステム クラス ローダーによってロードされません。)

于 2012-02-10T01:56:25.720 に答える