2011-09-30 4 views
9

:。差()getResourceAsStream()

/* 1 */ InputStream in1 = ClassLoader.getSystemResourceAsStream("foobar.txt"); 
/* 2 */ InputStream in2 = this.getClass().getResourceAsStream("/foobar.txt"); 

は、どちらも同じリソースを(私は答えの "はい" と思う)を返すのですか?

両方とも「同じ」クラスパスにアクセスしていますか? #1のメソッド名が "システム ResourceAsStream"になっていますが、#2の場合は単に "getResourceAsStream"ですか?

おかげ

答えて

7

のjavadoc

読み込み用にオープンし、クラスをロードするために使用される検索 パスから、指定された名前のリソースによります。このメソッドは、リソースをシステムクラスローダ (getSystemClassLoader()を参照)を介して探します。

ロードするクラスローダーthisは必ずしもシステムクラスローダーである必要はありません。シンプルなデスクトップアプリでは、これはおそらく真実です。しかし、Webアプリケーション(他のものの中でも)は、通常、より複雑なクラスパス階層を持ち、必ずしも同じではありません。複雑なクラスパスでは、返されるものはクラスパスの周りに浮かび上がるfoobar.txtのコピー数にも依存します。

簡単な答えは、同じリソースのストリームを返すと想定できないということです。

+0

Webアプリケーションに複数のクラスパスがあると言っていますか? @マイケル - 並べ替えの。 – Michael

+0

。通常、各Webアプリケーションは、WAR、EARなどの内容を担当する独自のクラスローダを取得します。これらのクラスローダは共通の親を持ち、共通のlibディレクトリのクラスはさまざまなWebアプリケーション間で共有されます。しかし、これらの階層はいくつかのローダーになる可能性があります。システムクラスローダーは一番上にありますが、その間に番号があります。 – sblundy

+0

異なるWebアプリケーションには、おそらく異なるクラスローダーがあります。たとえば、Glassfishでは、次の階層が指定されています(http://download.oracle.com/docs/cd/E19798-01/821-1752/6nmndgmhr/index.html#fvxzq)。 – g051051

11

主な違いは、クラスローダです。

この1つは、両方の文がまったく同じかどうかを振る舞うかどうか、に依存し、言い換えればgetClass()
this.getClass().getResourceAsStream("/foobar.txt");

によって返されたクラスローダを使用していますが、次はシステムクラスローダ
ClassLoader.getSystemResourceAsStream("foobar.txt");

を使用していますアプリケーションクラスローダー。単純なアプリケーションの場合、両方とも同じクラスローダーを参照します。しかし、ほとんどのアプリケーション(サーブレットコンテナ内で実行されているWebアプリケーションなど)では、そうではありません。

一般に、getClass()。getResourceAsStream()は、コードが属するクラスと同じクラスローダーを使用するため、より良い選択となります。

関連する問題