2009-07-06 19 views
17

可能性の重複:
How do you find all subclasses of a given class in Java?クラスのすべてのサブクラスを取得することは可能ですか?

こんにちは、

私はせずに検索サービスを行うことができますので、実行時にJavaでインターフェイスを実装するクラスのリストを取得したいと思いますそれをハードコーディングする。これを行う簡単な方法はありますか?私は恐れていない。

+1

C#では、アセンブリ内のすべてのクラスの定義を反復し、これらの各クラスをテストして、そのインターフェイスを実装するかどうかを確認できます。 – ChrisW

+3

悲しいことに、質問はC#についてではありません。 – Tom

+1

重複していますか? 「どのようにJavaで特定のクラスのすべてのサブクラスを見つけるのですか?」、http://stackoverflow.com/questions/492184/how-do-you-find-all-subclasses-of-a-given-class-in- java – Jonik

答えて

24

短い答えはノーです。

長い答えは、サブクラスがさまざまな形で存在することができ、基本的にすべてを見つけることが不可能であるということです。

実行時には実行できませんが、ロードされるまでクラスを見つけることができず、ロードされていることをどのように知っていますか?すべてのJARファイルとクラスファイルをスキャンできますが、それは決定的ではありません。さらに、URLクラスローダーのようなものがあります。

インナークラス(静的および非静的)も考慮する必要があります。名前付き内部クラスは簡単に見つかります。匿名の内部クラスは潜在的に見つけるのがはるかに困難です。

クラスにサブクラスがある場合、後で新しいサブクラスを作成できることも考慮する必要があります。

-2

ディスクまたはURLからクラスをロードするだけの場合は、クラスパスをスキャンして、サブクラスを「手動」で見つけることができます。

0

私はここで答えを理由づけようとしているので、間違っている可能性があります。ある時点で誰かがあなたのクラスの新しいサブクラスを作ることができるので、クラスがその子孫またはサブクラスに関する情報を持つことは意味がありません。その後、毎回この新しい情報を含むようにクラスを再コンパイルする必要があります。これは拡張可能なコードには意味がありません。クラスがその祖先に関する情報を含む可能性が高くなります。だから私が見ることができる唯一の解決策は、あなたの問題空間のすべてのクラスを繰り返しチェックすることですが、これはおそらく恐ろしい解決策です。

1

私はいつも非最終クラスの新しいサブクラスを作成し、クラスパスにサブクラスを追加して、あなたの意図を破ることができます。サブクラス化は自由な命題です。

あなたができることは、特定のクラスパスに対して、サブクラスが何であるかを知っていれば、クラスパス内の各クラスをスキャンする必要があるということです。

1

リフレクションを使用するとかなり簡単です。 「JavaWorld

http://www.javaworld.com/javaworld/javatips/jw-javatip113.html

+0

私は疑問を誤解しました、上記の記事は特定のインターフェイスを実装するサブクラスを見つけることです –

+0

このコードは、特定のパッケージ。しかし、どのパッケージにもサブクラスが存在する可能性があります。この記事では、「特定のインタフェースを実装するすべてのクラスに興味がありますが、そのような情報はJava Reflectionで利用できません」と述べています。 –

1

からこの記事を読んで、あなたがそれを行うことができるだろう唯一の方法は、リフレクション経由で各クラスを確認し、クラスパスにパッケージのパッケージ階層が利用可能に歩いている(そしてそれはつもりだあなたのために吸います特定のパッケージに検索を制限しない限り、すべてのクラスを効果的にロードします)。

このような自動魔法の動作の問題は、アプリケーションを実行せずにアプリケーションを定量化することが難しくなることです。これはメンテナンスの頭痛です。私はいつも、ある種の構成を経てインスタンスを通過する注入ルート(a-la Spring)に行くことを好むでしょう。

0

特定のインターフェイスを実装するクラスを列挙するか、いくつかの基本クラスから派生したクラスを列挙しますか?これらは2つの異なる問題です。私が知っている限り、実装するのは難しいでしょう。新しい実装は、いつでもPC上に作成/インストールできるからです。特定のインスタンスをインスタンス化するためのファクトリメソッドを作成しようとしていて、コード内のクラス名をハードコードしたくないように思えます。通常、インターフェイスを実装するすべてのクラスを列挙する設定ファイルを使用して、(またはデータベースを使用する)方法があります。新しいクラスがインターフェイスを実装すると、それらをコンフィグファイルに追加し、ファクトリは新しいクラス名を取得する必要があります。

5

組み込みクラスのJava ServiceLoaderを使用する必要があります。実行時にすべての既知のサービス(インタフェース)実装に対して反復処理が可能です。

何らかの理由でClassLoader.getSystemResources()を使用してすべてのリソースを反復処理できます。例えば/META-INF/com.interfaceファイルの6倍の場合、6回の反復が行われます。

関連する問題