1

私たちが知っているように、Javaは消去を使用するため、ジェネリッククラスはできません

T t = new T();

だから私は Java リフレクションを試して、静的メソッドを持つクラスを持ち、任意のクラスを任意のコンストラクターでインスタンス化しました。これがコードです。

import java.lang.reflect.*;

public class GenericNewInstance {
    public static <T> T createInstance(Class<T> cObj) {
        try {
            return cObj.newInstance();
        } catch (InstantiationException e) {
            System.out.println("Instantiation Exception");
            return null;
        } catch (IllegalAccessException e) {
            System.out.println("Illegal Access Exception");
            return null;
        }
    }

    public static <T> T createInstanceUsingRelection(Class<T> c, Object... initArgs) {
        Constructor<T> cTor = null;
        Class<?>[] cObjs = new Class<?>[initArgs.length];
        int i = 0;

        for(Object o : initArgs) {
            cObjs[i++] = o.getClass();
        }

        try {
            cTor = c.getConstructor(cObjs);
        } catch (SecurityException e) {
            System.out.println("security exception. Cannot get Constructor");
            return null;
        } catch (NoSuchMethodException e) {
            System.out.println("NoSuchMethodException Cannot get constructor");
            return null;
        }

        try {
            return cTor.newInstance(initArgs);
        } catch (IllegalArgumentException e) {
            System.out.println("Illegal Argument Exception");
            return null;
        } catch (InstantiationException e) {
            System.out.println("Instantiation Exception");
            return null;
        } catch (IllegalAccessException e) {
            System.out.println("Illegal Access Exception");
            return null;
        } catch (InvocationTargetException e) {
            System.out.println("Invocation Target Exception");
            return null;
        }
    }
}

これを使用する例。

Integer i = GenericNewInstance.createInstanceUsingRelection(Integer.class, "0");

だから私の質問:

  1. これはそれを実装する正しい方法ですか?(または冗長ですか?)
  2. これを行う典型的なユースケースは何ですか?
  3. Generics を使用している間、Re​​flection の使用を避けることができますか?
4

1 に答える 1

6

c.getConstructor(cObjs)これは型階層を考慮していないため、コードは失敗します。いずれかの引数がコンストラクターの宣言された param 型のサブタイプである場合、この呼び出しはそれを返しません。それを機能させるには、さらに多くの型のジャグリングが必要になります。すでにこの問題を解決しているコードを参照することをお勧めします。おそらく、そのライブラリをそのまま使用することもできます。これは、まさにこれを必要とする JVM ベースの動的言語である Clojure の実装コードです。ライブラリは、Maven セントラル リポジトリから入手できます。

ところで、例外処理は冗長です。いずれかを宣言throws ExceptionまたはキャッチExceptionして、RuntimeException. 何かが失敗した場合、元の例外が最良の診断になります。

于 2012-07-14T19:57:09.960 に答える