如何确定泛型超类的特定子类的实际返回类型



我知道我试图做的事情在纯java中是不可能的——只有当我查看调试信息时才有可能。无论如何,我不会在没有调试的情况下进行编译,因为我的springmvc的buch将停止工作。

也就是说,我有以下情况:

一个通用超类:

软件包com.cinefms.apitester.springmvc.craclers;

public class TestGenerics<T extends TestGenericsInterface> {
    public T get() {
        return null;
    }
    public T put(T t) {
        return null;
    }
}

及其子类:

package com.cinefms.apitester.springmvc.crawlers;

public class TestGenericsSub extends TestGenerics<TestGenericsImpl> {
}

里面的东西真的很简单。

一个接口:

package com.cinefms.apitester.springmvc.crawlers;
public interface TestGenericsInterface {
}

及其实现:

package com.cinefms.apitester.springmvc.crawlers;
public class TestGenericsImpl implements TestGenericsInterface {
}

eclipse很好地计算出TestGenericsSub.get()应该返回TestGenericsImpl的实例。。。即使没有可用的源。

但是我怎么可能在运行时自己解决这个问题呢?

如果"m"是方法"run",则

m.getGenericReturnType();

会返回"T"(没有帮助),而:

m.getReturnType();

给了我"TestGenericsInterface"(也没有帮助)。我一直在看"org.javaruntype"库。。。但我似乎想不通。

有人能解释一下吗?

谢谢!

您可以使用ClassMate:实现这一点

TypeResolver typeResolver = new TypeResolver();
MemberResolver memberResolver = new MemberResolver(typeResolver);
ResolvedType resolvedType = typeResolver.resolve(TestGenericsSub.class);
ResolvedTypeWithMembers resolvedTypeWithMembers = memberResolver.resolve(resolvedType, null, null);
ResolvedMethod resolvedGetMethod = resolvedTypeWithMembers.getMemberMethods()[0];
System.out.println(resolvedGetMethod.getReturnType()); // TestGenericsImpl

感谢Java类型的擦除(https://docs.oracle.com/javase/tutorial/java/generics/genTypes.html),这很难。我建议将类保存为一个属性,然后如果您绝对必须知道T.的运行时类型,则提供一个getter

public class MyGenericClass<T> {
    private final Class<T> type;
    public MyGenericClass(Class<T> type) {
        this.type = type;
    }
    public Class<T> getMyType() {
        return this.type;
    }
}

否则,您可以尝试以下操作:

(Class<T extends TestGenericsInterface>) ((TestGenerics) getClass().getGenericSuperclass()).getActualTypeArguments()[0];

在代码方面,我更喜欢前者的解决方案而不是后者。

最新更新