10

リフレクションなどでそれを行うことはできますか?

4

1 に答える 1

10

あなたがやりたいことを100%信頼できる方法はありません。その理由は、Java でクラスのロードがどのように機能するかによるものです。

Java では、クラスは「オンデマンド」でロードされます。クラスがコード内で初めて (静的または動的に) 参照されると、JVM は現在のクラス ローダーを使用してそれをロードしようとします。ClassLoader には、そこからロードできるすべてのクラスを提供するメソッドがないため、クラスを反復処理することはできません。

信頼できない回避策がいくつかあります。たとえば、ClassLoader が特定のディレクトリまたは特定の JAR ファイル内からのみクラスをロードすることがわかっている場合、ファイル システムに関連するクラスを使用して、利用可能な「.class」ファイルを見つけることができます。すべてをロードし (これには時間がかかり、PermGen を大量に消費するため、問題になる可能性があります。クラスを簡単にアンロードできないことを覚えておいてください! (ClassLoader マジックを実行しない限り))、リフレクションを使用して、実装しているクラスをフィルタリングします。インターフェース。

この回避策の問題点は、展開を変更した場合に機能しなくなる可能性が高いことです。たとえば、JAR ファイルのデプロイを開始した後、WAR ファイルを処理するサーブレット コンテナーを使用することにした場合、コードが機能しなくなる可能性があります。

このアプローチを本当に試してみたい場合は、Reflectionsというプロジェクトが役立ちます。

これを実装した中で最も信頼できる方法は、 Annotation Processor を使用することです。注釈を書き、インターフェイスに注釈を付け、コンパイル時にコンパイラによって実行されるコードを記述します。このコードは、インターフェイスを実装するクラスを収集し、それらの名前をリソース ファイルに保存します。次に、そのファイルを読み取り、そのリソース ファイルにリストされている各クラス名の Class オブジェクトを提供するメソッドを含むクラスを作成します。

このアプローチの問題は、ビルド プロセスでコンパイルされたクラスのみがリストされることです (つまり、インターフェイスを使用してライブラリを公開し、他のユーザーがインターフェイスを実装することを期待する場合、このアプローチは役に立ちません。他のプロジェクトのクラスについては決して知りません)。私の場合と同様に、これで十分な場合、このソリューションは問題なく機能します。WAR (展開されているかどうかに関係なく) 展開を使用するサーブレット コンテナーで、実行可能な jar ファイルなどで使用できます。それは常に機能します。

于 2013-03-09T06:06:20.407 に答える