获取继承的泛型方法的返回类型

时间:2019-10-21 08:03:48

标签: java generics inheritance

我有这3个班级

public class Box<O> {

    public O getItem() {...}

}
public class CoolBox extends Box<Integer> { ... }
public class AmazingBox extends CoolBox { ... }

在代码的某一时刻,我需要获取getItem()类的方法AmazingBox的返回类型,但是当通过反射访问其方法时,我得到Object为返回类型,而不是Integer

有什么方法(普通的Java或其他库)获取Integer作为返回类型?

这是我用来获取返回类型的代码:

Class<?> c = AmazingBox.class;  // This is not how i get the class but its for demonstration purposes

Method m = c.getMethod("getItem");

Type t = m.getReturnType();

2 个答案:

答案 0 :(得分:1)

我刚刚发现有一个名为GenericsResolver的库完全可以满足我的需求。

使用这段代码可以返回正确的类型

Class<?> clazz = AmazingBox.class;
GenericsContext genericsContext = GenericsResolver.resolve(clazz);
Method method = clazz.getMethod("getItem");
Type methodReturnType = genericsContext.method(method).resolveReturnType();

答案 1 :(得分:1)

在继承时,您可以使用泛型来继承类,并相应地创建下限或上限。如果不这样做,则假定您在不使用泛型的情况下工作,并且在继承非泛型类时不会获得类型安全性。

简而言之,如果您采用混合模式,type erasures将遵循以下规则(参考文档)生效

  

类型擦除

     

泛型被引入Java语言,以在编译时提供更严格的类型检查并支持泛型编程。为了实现泛型,Java编译器将类型擦除应用于:

     
      
  • 如果类型参数不受限制,请用其界限或对象替换通用类型中的所有类型参数。因此,产生的字节码仅包含普通的类,接口和方法。
  •   
  • 必要时插入类型强制转换以保持类型安全。
  •   
  • 生成桥接方法以在扩展的泛型类型中保留多态。
  •   
     

类型擦除确保没有为参数化类型创建新的类;因此,泛型不会产生运行时开销。