9

重複の可能性:
リフレクションとは何ですか、なぜそれが役立つのですか?

Javaでのリフレクションの正確な使用法は何ですか?誰かが例を挙げてデモンストレーションできますか?関連する概念があれば、共有してください。

4

2 に答える 2

11

リフレクションは強力な構成であり、GuiceやHibernateなどの基盤となるライブラリで作業を楽にするためによく使用されます。これは、クラスを構成してその場でインスタンス化する必要がある場合によく使用されます。例えば:

public Strategy prepare(String clazz, Properties config) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
    Class<?> clazz = Class.forName(clazz);
    Strategy strategy = (Strategy) clazz.newInstance();
    strategy.initialise(config);
    return strategy;
}

ここで、clazzパラメーターはインスタンス化するクラスに名前を付けます。このクラスは、Strategyクラス/インターフェイスのサブクラスであると想定されています。次に、configパラメーターを介して渡された設定で開始されます。これにより、高度に構成可能で動的な環境が可能になります。

ただし、リフレクションは非常に危険な(そして悪意のある)コードにつながることが非常に多いため、絶対に必要な場合を除いて、リフレクションは避ける必要があります。また、リフレクションは直接呼び出しよりも遅いことにも注意してください。これは、リフレクションを使用しない方法の実動システムから引き出された実際の例です。

private static CacheManager getRawInstance() {
    lock.lock();
    try {
        final Field field = CacheManager.class.getDeclaredField("singleton");
        field.setAccessible(true); // << -- ??
        return (CacheManager) field.get(CacheManager.class);
    } catch (Exception e) {
        logger.error(e.getMessage(), e);
        return null;
    } finally {
        lock.unlock();
    }
}

ここでは、ehcacheのプライベートフィールドが変更されてアクセスされます。これはまったく悪いコーディングです。

于 2013-01-16T07:01:08.303 に答える
1

TechExchangeは、リフレクションを説明する素晴らしい仕事をしました。リフレクションはJavaでは黒い羊のようです。それはバグが多くエラーが発生しやすいと人々が言うのをいつも耳にしますが、それが正しく行われるとかなり安定していて効率的であることがわかりました。私はそれを使用することを避け、ネイティブリフレクションコードを書くことよりもイントロスペクションライブラリを試してみようと言います。イントロスペクションはリフレクションと同じもので、通常は基礎となるリフレクションライブラリ上に構築されたライブラリです。Beanを使用している場合、SpringとApache-commonsの両方に優れたツールがあります。

SpringとApacheはゲッターのみを対象としていますが、残念ながら、私はBeanの世界に住んでいません。私が使用しなければならなかったオブジェクトのいくつかはブール値の'is'メソッドであり、リフレクションコードを記述していることに気づきました。

とにかくここに、引数が0のすべてのパブリックメソッドを格納する単純なリフレクションコードがあります。

public void foo(final Class _class){
    List<Method> methods = new ArrayList<Method>(){{
        for( Method method : _class.getMethods() ) {

            if( Modifier.isPublic( method.getModifiers() ) 
                && method.getGenericParameterTypes().length == 0 ){

            add(method);
        }
    }};
}
于 2013-01-16T07:14:57.323 に答える