こんにちは、
実行時にJavaでインターフェイスを実装するクラスのリストを取得して、ハードコーディングせずにルックアップサービスを実行できるようにしたいのですが、これを行う簡単な方法はありますか?恐れるな。
簡単な答えはノーです。
長い答えは、サブクラスはさまざまな方法で存在する可能性があるため、基本的にすべてを分類して見つけることは不可能であるということです。
実行時にそれを行うことはできませんが、クラスがロードされるまでクラスを見つけることができず、クラスがロードされていることをどのようにして知ることができますか?すべてのJARおよびクラスファイルをスキャンできますが、それは決定的なものではありません。さらに、URLクラスローダーのようなものがあります。
内部クラス(静的および非静的)は、考慮すべきもう1つのケースです。名前付きの内部クラスは見つけやすいです。匿名の内部クラスは、見つけるのがはるかに難しい可能性があります。
また、クラスにサブクラスがある場合は、後で新しいサブクラスを作成できることも考慮する必要があります。
組み込みクラスであるJava ServiceLoader を使用する必要があります。実行時にすべての既知のサービス(インターフェース)実装を反復処理できます。
何らかの理由でそれを望まない場合は、ClassLoader.getSystemResources()を使用してすべてのリソースを反復処理できます。例えばファイル/META-INF/com.interfaceが6倍ある場合、6回の反復が行われます。
それを行うことができる唯一の方法は、クラスパスで利用可能なパッケージのパッケージ階層をウォークして、リフレクションを介して各クラスをチェックすることです(特定のパッケージに検索を制限しない限り、すべてのクラスを効果的にロードするため、これは面倒です。 )。
この種の自動魔法の動作の問題は、アプリケーションを実行せずにアプリケーションを定量化することが困難になることです。これは、メンテナンスの頭痛の種です。私は常に、ある種の構成を介してインスタンスを渡すインジェクションルート(a-la Spring)を使用することを好みます。
私はいつでも非最終クラスの新しいサブクラスを作成し、そのサブクラスをクラスパスに追加して、あなたの意図を打ち負かすことができます。サブクラス化は自由形式の提案です。
最善の方法は、特定のクラスパスについて、サブクラスが何であるかを知っているということです。そのためには、クラスパス内の各クラスをスキャンする必要があります。
リフレクションを使用するのはかなり簡単です。 JavaWorldからこの記事を読む
http://www.javaworld.com/javaworld/javatips/jw-javatip113.html
特定のインターフェイスを実装するクラスを列挙しますか、それともいくつかの基本クラスから派生するクラスを列挙しますか?これらは2つの異なる問題です。新しい実装は将来いつでもPCに作成/インストールできるため、私が知る限り、どちらも実装するのは難しいでしょう。特定のインスタンスをインスタンス化するファクトリメソッドを作成しようとしていて、コードにクラス名をハードコーディングしたくないようです。通常、インターフェイスを実装するすべてのクラスを列挙する構成ファイルを使用するのが方法です(またはデータベースを使用できます)。新しいクラスがインターフェイスを実装したら、それらを構成ファイルに追加すると、ファクトリは新しいクラス名を取得する必要があります。
私はここでの答えを通して推論しようとしているので、おそらく間違っています。クラスがその子孫またはサブクラスに関する情報を持っていることは、いつでも誰かがクラスの新しいサブクラスを作成できるため、意味がありません。次に、クラスを再コンパイルして、毎回この新しい情報を含める必要があります。これは、拡張可能なコードには意味がありません。クラスには、その祖先に関する情報が含まれている可能性が高くなります。したがって、私が見ることができる唯一の解決策は、問題空間のすべてのクラスを繰り返して確認することですが、これはおそらくあなたにとって恐ろしい解決策です。