2012-02-06 18 views
6

私はリフレクションでメソッドを呼び出しています。その戻り値の型はジェネリックです。私は戻り値がnullであることを望んでいないので、その場合はその汎用タイプのデフォルト値を割り当てたいと思います。ジェネリックへのデフォルト値の割り当て

T resultNotNull = (T) reflectionMethodThatCanReturnNull.invoke(anObject); 
// If it's null, let's assign something assignable. 
if (resultNotNull == null) { 
    if (resultNotNull.getClass().isAssignableFrom(Long.class)) { 
     resultNotNull = (T) Long.valueOf(-1); 
    } else if (resultNotNull.getClass().isAssignableFrom(String.class)) { 
     resultNotNull = (T) "NOTHING"; 
    } 
} 

しかし、「resultNotNull == nullを」の場合、もちろん、我々はできません:、反射によってメソッドを呼び出した後で、私はこのような何かを実行したいと思います

例外を取得せずに 'resultNotNull.getClass()'を呼び出します。

ジェネリックタイプに応じてデフォルト値を割り当てる方法に関するアイデアはありますか?

全体のコードは次のようになります。

public class ReflectionTest { 
    public class Class1ok { 
     public Long method() { return Long.valueOf(1); } 
    } 
    public class Class1null { 
     public Long method() { return null; } // It returns null 
    } 
    public class Class2ok { 
     public String method() { return "SOMETHING"; } 
    } 

    public static void main(String[] args) { 
     ReflectionTest test = new ReflectionTest(); 

     Long notNullValue1 
      = test.methodReturnNotNull(Class1ok.class); // 1 
     Long notNullValue2 
      = test.methodReturnNotNull(Class1null.class); // -1, not null 
     String notNullValue3 
      = test.methodReturnNotNull(Class2ok.class); // "SOMETHING" 
    } 

    public <T> T methodReturnNotNull(Class theClass) { 
     T resultNotNull = null; 
     try { 
      Object theObject = theClass.newInstance(); 
      Method methodThatCanReturnNull = theClass.getMethod("method"); 
      resultNotNull = (T) methodThatCanReturnNull.invoke(theObject); 
     } catch (Exception e) { 
      // Meh. 
     } 

     // If it's null, assign something assignable. 
     if (resultNotNull == null) { 
      if (resultNotNull.getClass().isAssignableFrom(Long.class)) { 
       resultNotNull = (T) Long.valueOf(-1); 
      } else if (resultNotNull.getClass().isAssignableFrom(String.class)) { 
       resultNotNull = (T) "NOTHING"; 
      } 
     } 
     return resultNotNull; 
    } 
} 

答えて

3

あなたはgetReturnType()を使用することができます。

private static final Map<Class, Object> replacementForNull = new HashMap<>(); 
static { 
    replacementForNull.put(String.class, "NOTHING"); 
    replacementForNull.put(Long.class, 1L); 
} 


Method reflectionMethodThatCanReturnNull = ... 
T resultNotNull = (T) reflectionMethodThatCanReturnNull.invoke(anObject); 
// If it's null, let's assign something assignable. 
if (resultNotNull == null) { 
    Class returnType = reflectionMethodThatCanReturnNull.getReturnType(); 
    resultNotNull = replacementForNull.get(returnType); 
} 
+0

getReturnType()が返されませんオブジェクトを返しますか? Genericsはコンパイル時に消去されます。 – Pablo

+0

戻り値の型がObjectまたはObjectを返すGenericの場合、getReturnType()はObjectを返します。上記の例では 'Long'と' String'となります。 –

+0

OK、私は質問を誤読しました。私は彼がメソッド "メソッド"が一般的であることを意味していると思っていました。 – Pablo

0

なぜあなたのTは、インターフェイスを実装できないか、基本クラスを拡張できないのですか?次に、指定されたクラスTのデフォルト値を返すTから静的デフォルトメソッドを呼び出すことができます。長所? switchコードを適切なクラスにカプセル化します。

もちろん、インターフェイスがなければ、可能なすべてのTクラスは、getDefaultValue()のようなメソッドを持つことができます。

+0

いいえ、Tクラスを変更してgetDefaultValue()メソッドを追加することや、返される内容を変更することはできません。 –

関連する問題