Java 使用默认方法从参数化接口提取类

Java 使用默认方法从参数化接口提取类,java,reflection,types,Java,Reflection,Types,如何在接口中使用Java8默认方法来提取参数化类型的类,而不是使用抽象类 选项1(失败): 公共接口{ 默认类GetParameteredTypeClass(){ return T.class;//不起作用 } 选项2(失败): 公共接口{ 默认类GetParameteredTypeClass(){ 返回(类)((ParameterizedType)getClass().getGenericInterfaces()[0]) .getActualTypeArguments()[0]; //jav

如何在接口中使用Java8默认方法来提取参数化类型的类,而不是使用抽象类

选项1(失败):

公共接口{
默认类GetParameteredTypeClass(){
return T.class;//不起作用
}
选项2(失败):

公共接口{
默认类GetParameteredTypeClass(){
返回(类)((ParameterizedType)getClass().getGenericInterfaces()[0])
.getActualTypeArguments()[0];
//java.lang.ClassCastException:java.lang.Class不能转换为java.lang.reflect.ParameterizedType
}
第三次尝试(成功但没有接口):

公共抽象类CoolAbstractClass{
私人课堂;
公共类(){
试一试{
this.clazz=(类)((ParameterizedType)getClass().getGenericSuperclass())
.getActualTypeArguments()[0];
}捕获(例外e){
抛出新的运行时异常(e);
}
}
公共类getType(){
回击声;
}
}

实际上,您需要的是泛型类型推断

尽管您的第三次尝试有效,但它仅适用于指定情况(该类直接扩展了抽象类)

您可以使用我的实用程序类
GenericUtil
的方法

Type[] getGenericTypes(Type sourceType, Class<?> targetClass)
Type[]getGenericTypes(类型sourceType,类targetClass)
您可以在上找到源代码和javadoc

对于你的问题,你可以这样定义你的界面:

  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];
    }
  }
公共静态接口{
//返回类型而不是类,因为T不总是类。
//您可以使用forcetypecast进行类型检查和返回类。
默认类型GetParameteredTypeClass(){
返回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());
  }
publicstaticvoidmain(字符串[]args){
EpicCoolInterface a=新的EpicCoolInterface(){
};
System.out.println(a.getParameteredTypeClass());
EpicCoolInterface b=新的EpicCoolInterface(){
};
System.out.println(b.getParameteredTypeClass());
接口>(){
};
System.out.println(c.getParameteredTypeClass());
}
it输出:

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<?>
类java.lang.Integer
xdean.stackoverflow.java.reflection.Q46360416.xdean.stackoverflow.java.reflection.Q46360416$EpicCoolInterface
xdean.stackoverflow.java.reflection.Q46360416.xdean.stackoverflow.java.reflection.Q46360416$EpicCoolInterface
  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<?>