4

通常の Java コードからリフレクション スタイルの Java コードを作成するコンバーターを探しています。私はこれを行って、次のような例外を防ぎますNoClassDefFoundError(クラスに依存したいが、使用しているライブラリにその依存クラスがない場合、Java にコードを単に無視させたい)。

私はこのようなコンバーターを期待しています:

初期コード:

com.foo.MyClass myClass = new com.foo.MyClass()
myClass.meth1();

変換後:

Object myClass = Class.forName("com.foo.MyClass").newInstance();
myClass.getMethods("meth1").invoke(myClass);
4

2 に答える 2

1

これは技術的に可能なアプローチかもしれませんが、他のポスターと同様に、これが問題を解決する正しい方法であるかどうかを検討することをお勧めします (元の問題を解決する方法ではなく、このソリューションを実装する方法を尋ねたので、私は正しい軌道に乗っているかどうかはわかりません)。

オプションでライブラリに依存することに興味があるかもしれませんが、クライアントにライブラリの提供を強制するのではありませんか? ビルド システムによっては、これを達成するのはそれほど難しくありません。たとえば、Maven では、依存関係を として指定できます<scope>optional</scope>。これにより、それに対してコードをコンパイルできますが、それを推移的な依存関係として含めることはできません。

そうは言っても、オプションで特定のライブラリに依存し、それらが利用できない場合は別のルートを取ることは確かに可能です。私の経験では、これはインターフェイスの背後にある詳細を隠すことで最も簡単に実現できます。

例として、AspectJ アスペクトと連携して、カスタム アノテーションでマークしたメソッドをプロファイリングする ProfilingAdvisor インターフェイスがあります。外部依存関係のない SimpleProfilingAdvisor と呼ばれるこのインターフェイスの初歩的な実装があります。私は、SimonProfilingAdvisor と呼ばれる、追加情報のために Java Simon ライブラリを使用する、より詳細な実装を行っています。

クライアントが Java Simon ライブラリを含めることを選択した場合、「より良い」実装が得られます。彼らがそうしないことを選択した場合、「基本」アプローチが実装されます(あなたの場合、何もしないことになるかもしれません)。

私のコードは常にインターフェイス ProfilingAdvisor に対して動作しますが、この型のインスタンス変数をインスタンス化するときは、オプションの Simon ライブラリがクラスパスにあるかどうかを判断する必要があります。

    private ProfilingAdvisor advisor;
    /* ... */
    try {
        Class.forName("org.javasimon.SimonManager");
        this.advisor = new SimonProfilingAdvisor();
    } catch (ClassNotFoundException classNotFoundException) {
        this.advisor = new SimpleProfilingAdvisor();
    }

最後に 1 点。あなたが示唆しているようにリフレクションを使用してクラスの存在を判断することはできますが、インスタンス化後にリフレクション メソッドにアクセスすることで得られるものは何も考えられません。メソッド名のスペルなど。

少なくとも、コンパイル時にライブラリに対してコンパイルできるビルド システムを使用する必要がありますが、後でディストリビューションに含める必要はありません (Maven など)。

于 2010-08-10T15:13:23.020 に答える
1

Java コードでのリフレクションの使用をできるだけ避けるようにしてください。@mwittrockで提案されているような他のアプローチを使用して、それらを取得しないようにすることができますNoClassDefFoundError

リフレクションを使用して問題を解決できるかもしれませんが、設計に新しい問題を導入する可能性があります。リフレクション コードの冗長性だけでなく、パフォーマンス コストも考慮してください。

コア リフレクション機能は、もともとコンポーネント ベースのアプリケーション ビルダー ツール用に設計されたものです。リフレクションを必要とする高度なアプリケーションがいくつかあります。例としては、クラス ブラウザ、オブジェクト インスペクタ、コード分析ツール、解釈型組み込みシステムなどがあります。アプリケーションがこれらのカテゴリのいずれかに該当するかどうか疑問がある場合は、おそらくそうではありません。

Joshua Bloch 著、「Effective Java」、第 2 版。

于 2010-08-10T14:14:47.013 に答える