ClassLoader.getResourceAsStream()とClass.getResourceAsStream()の違い
2575 ワード
From:http://www.cnblogs.com/yjl49/archive/2012/08/08/2628502.html
例えばあなたはMyTestクラスをパッケージcomに書いた.test.mycodeではclass.
このnameが'/'で始まるとclasspathのルートパスの下から検索が開始されます.
ClassLoader.getResourceAsStream()は、検索するリソースの前に'/'があるかどうかにかかわらずclasspathのルートパスの下から検索されます.
だから:getClassLoader().getResourceAsStream(「name」)と
MyTest.getClassLoader().getResourceAsStream(「name」)の効果は同じです.
ちなみにJAVAのクラスのローダは
全部で3種類のローダがあります
bootstrap classloader:JAVAコアクラス(jre下libとclassディレクトリの内容)のロードを担当します.
extension classloader:JAVA拡張クラス(jre下lib/extディレクトリの内容)のロードを担当
System classloader:アプリケーションで指定したクラス(環境変数classpathで構成された内容)のロードを担当します.
1つのクラスのロード順序も上のように並べられており、システムのクラスが先にロードされることを保証します.
同時に、ユーザーはClassLoaderを自分で定義して、特別なリソースをロードすることもできます.
ここではClassについてですgetClassLoader()とThread.currentThread.getContextClassLoader()の違い.
簡単な例を挙げます.
もしある日JAVAがStartCameraというクラスを提供してパソコンを起動するための標準カメラを提供してくれたら、このクラスをjarにパッケージします.
通常、カメラを起動するときは、このjarをclasspathに構成するだけです.システムが起動するとsystem classloaderはこのクラスをアプリケーションにロードします.
しかし、カメラのメーカーが異なるため、新しい機器に対して複数の異なるStartCameraが実現され、アプリケーションでは実際のユーザーがどのようなものを使うか分かりません.そこで、特定のデバイスタイプに対応するStartCameraクラスをロードするためのClassLoaderをカスタマイズしました.
これにより、定義したクラスを優先的にロードし、ロードできない場合にシステムをロードします.このようなニーズは、システムのデフォルトの親委任ロードメカニズムでは満たされません.
Thread.currentThread.getContextClassLoader()はこのように生成されます.私たちはThreadを使います.currentThread.setContextClassLoader()は、現在のスレッドに対応するClassLoaderを指定し、getで取得できます.
上のロードコードは次のようになります.
public
void useCamera(){
StartCamera s =
this.findClassLoader().loadClass("StartCamera");
s.start();
}
private ClassLoader findClassLoader(){
ClassLoader loader = Thread.currentThread().getContextClassLoader();
if(loader==
null){
loader = ClassLoader.getSystemClassLoader();
}
return loader;
}
Class.getResourceAsStream() 。
例えばあなたはMyTestクラスをパッケージcomに書いた.test.mycodeではclass.
getResourceAsStream("name")
はcomにいます.test.mycodeパッケージの下で対応するリソースを検索します.このnameが'/'で始まるとclasspathのルートパスの下から検索が開始されます.
ClassLoader.getResourceAsStream()は、検索するリソースの前に'/'があるかどうかにかかわらずclasspathのルートパスの下から検索されます.
だから:getClassLoader().getResourceAsStream(「name」)と
MyTest.getClassLoader().getResourceAsStream(「name」)の効果は同じです.
ちなみにJAVAのクラスのローダは
全部で3種類のローダがあります
bootstrap classloader:JAVAコアクラス(jre下libとclassディレクトリの内容)のロードを担当します.
extension classloader:JAVA拡張クラス(jre下lib/extディレクトリの内容)のロードを担当
System classloader:アプリケーションで指定したクラス(環境変数classpathで構成された内容)のロードを担当します.
1つのクラスのロード順序も上のように並べられており、システムのクラスが先にロードされることを保証します.
同時に、ユーザーはClassLoaderを自分で定義して、特別なリソースをロードすることもできます.
ここではClassについてですgetClassLoader()とThread.currentThread.getContextClassLoader()の違い.
簡単な例を挙げます.
もしある日JAVAがStartCameraというクラスを提供してパソコンを起動するための標準カメラを提供してくれたら、このクラスをjarにパッケージします.
通常、カメラを起動するときは、このjarをclasspathに構成するだけです.システムが起動するとsystem classloaderはこのクラスをアプリケーションにロードします.
しかし、カメラのメーカーが異なるため、新しい機器に対して複数の異なるStartCameraが実現され、アプリケーションでは実際のユーザーがどのようなものを使うか分かりません.そこで、特定のデバイスタイプに対応するStartCameraクラスをロードするためのClassLoaderをカスタマイズしました.
これにより、定義したクラスを優先的にロードし、ロードできない場合にシステムをロードします.このようなニーズは、システムのデフォルトの親委任ロードメカニズムでは満たされません.
Thread.currentThread.getContextClassLoader()はこのように生成されます.私たちはThreadを使います.currentThread.setContextClassLoader()は、現在のスレッドに対応するClassLoaderを指定し、getで取得できます.
上のロードコードは次のようになります.
public
void useCamera(){
StartCamera s =
this.findClassLoader().loadClass("StartCamera");
s.start();
}
private ClassLoader findClassLoader(){
ClassLoader loader = Thread.currentThread().getContextClassLoader();
if(loader==
null){
loader = ClassLoader.getSystemClassLoader();
}
return loader;
}