2017-09-22 12 views
2

を使用してパラメータ付きインターフェイスからクラスを抽出する抽象クラスを使用する代わりに、インターフェイスでJava 8のデフォルトメソッドを使用してパラメータ化されたタイプのクラスを抽出するにはどうすればよいですか?デフォルトメソッド

オプション1(失敗):

public interface EpicCoolInterface<T> { 

default Class<T> getParameterizedTypeClass() { 
    return T.class; //doesn't work 
} 

オプション2(失敗):

public interface EpicCoolInterface<T> { 

default Class<T> getParameterizedTypeClass() { 
    return (Class<T>) ((ParameterizedType) getClass().getGenericInterfaces()[0]) 
    .getActualTypeArguments()[0]; 
    //java.lang.ClassCastException: java.lang.Class cannot be cast to java.lang.reflect.ParameterizedType 
} 

サード(成功したが、無インタフェース)の試行:

public abstract class CoolAbstractClass<T> { 

    private Class<T> clazz; 

    public CoolAbstractClass() { 
    try { 
     this.clazz = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()) 
      .getActualTypeArguments()[0]; 
    } catch (Exception e) { 
     throw new RuntimeException(e); 
    } 
    } 

    public Class<T> getType() { 
    return clazz; 
    } 
} 

答えて

1

実際には、何一般的な型推論が必要です。

3回目の試みは機能しますが、状況を指定するためにのみ適用できます(クラスは抽象クラスを直接拡張します)。

あなたがgithubにソースコードとJavadocを見つけることができる私のユーティリティクラスGenericUtilの方法

Type[] getGenericTypes(Type sourceType, Class<?> targetClass) 

を使用することができます。あなたの質問のために

、あなたはこのようなあなたのinteerfaceを定義することができます。

public static interface EpicCoolInterface<T> { 
    // Return Type rather than Class, because T not always be a class. 
    // You can do type check and return Class<T> with force typecast. 
    default Type getParameterizedTypeClass() { 
     return GenericUtil.getGenericTypes(getClass(), EpicCoolInterface.class)[0]; 
    } 
    } 

そして、私たちのコードをテストしてみましょう:

public static void main(String[] args) { 
    EpicCoolInterface<Integer> a = new EpicCoolInterface<Integer>() { 
    }; 
    System.out.println(a.getParameterizedTypeClass()); 
    EpicCoolInterface<EpicCoolInterface<Integer>> b = new EpicCoolInterface<EpicCoolInterface<Integer>>() { 
    }; 
    System.out.println(b.getParameterizedTypeClass()); 
    EpicCoolInterface<EpicCoolInterface<?>> c = new EpicCoolInterface<EpicCoolInterface<?>>() { 
    }; 
    System.out.println(c.getParameterizedTypeClass()); 
    } 

その出力:

class java.lang.Integer 
xdean.stackoverflow.java.reflection.Q46360416.xdean.stackoverflow.java.reflection.Q46360416$EpicCoolInterface<java.lang.Integer> 
xdean.stackoverflow.java.reflection.Q46360416.xdean.stackoverflow.java.reflection.Q46360416$EpicCoolInterface<?> 
関連する問題