java - 有没有什么技巧可以在运行时知道实例泛型的实际具体类?

标签 java generics inheritance reflection java-8

<分区>

我想找到一个 hack 来在运行时推断另一个实例的 var 的实际通用实例,没有:

  • 更改我需要的方法签名(添加辅助参数 Class<T>,最明显的方法)
  • 不得不 instanceof以硬编码方式显示所有可能的子类型

    MyInterface<? extends Number> myInterface = whateverReturnsWildcardDoubleInterface();
    Class<?> type = inferInstanceType(myInterface);
    assert type == Double.class;  
    
    /** This is the method that represents the code I am looking for  with the conrete signature**/
    public <T extends Number> Class<T> inferInstanceType(MyInterface<T> myInterface){
        return T.class; //Concrete T (can or cannot be the very Number)  
    }
    

理想情况下,当 T 是特定子类型 Integer,Double.. 时它应该返回 Double,当 T 是 Number 时它应该返回 Number

我检查了反射,几个“TypeResolver”/“GenericResolver”库(如 Spring 中的库或 Github 中的其他库),但我找不到破解它的方法。

编辑:我得出的结论是,他唯一可行的方法是通过堆栈跟踪进行某种非常复杂的反射,直到在实例化中传递类型的实际行

EDIT2:我知道这很愚蠢...但我通过简单地添加 T getT() 解决了它方法到我的界面,所以我可以 return myInterface.getT().getClass()

最佳答案

免责声明:此解决方案作为黑客提供,根据我对您的设置的理解量身定制,即一个通用接口(interface),具有单个类型参数,多个类,这些不是本身是通用的,直接单独实现这个接口(interface),不直接或间接实现其他通用接口(interface)。

假设以上所有内容都是正确的,有一种相对简单的破解解决方案的方法:调用 getClass().getGenericInterfaces() 返回一个 Type 对象提供已实例化通用接口(interface)的实际类型。

interface MyInterface<T extends Number> {
    T getVal();
}
class DoubleImpl implements MyInterface<Double> {
    public Double getVal() {return 42.42; }
}
...
public static void main (String[] args) throws java.lang.Exception {
    MyInterface<? extends Number> x = new DoubleImpl();
    Type[] ifs = x.getClass().getGenericInterfaces();

    System.out.println(ifs.length);
    for (Type c : ifs) {
        System.out.println(c);
        Type[] tps = ((ParameterizedType)c).getActualTypeArguments();
        for (Object tp : tps) {
            System.out.println("===="+tp); // <<== This produces class java.lang.Double
        }
    }
}

Demo.

关于java - 有没有什么技巧可以在运行时知道实例泛型的实际具体类?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34271256/

相关文章:

java - 如何使用其中包含 actionPerformed 的 IF 语句从另一个类检查一个类中的 JToggleButton 状态?

java - CORDA 无法将状态更改为在流中消耗

java - 使用Java以编程方式读取存储在HDFS中的文本文件的内容

C#:重载具有不同类型参数的 LINQ 泛型方法

java - 如何设置 javac 编译器标志来生成 1.7 字节码?

java - 为什么 Java 的 Class<T> 是泛型的?

C# 需要对新约束进行解释 (new T(...))

java - 如何检查 scala 类是否可以从 java 类分配

java - 扩展抽象类后的方法

javascript - functionName() 和 functionName.call(this) 之间的区别