如何确定通用超类的特定子类的ACTUAL返回类型?

时间:2014-11-09 06:59:11

标签: java generics inheritance runtime

我知道我想要做的事情并不是真的可以用纯java - 只有我看看调试信息才有可能。无论如何我都不会在没有调试的情况下编译,因为我的春天mvc会停止工作。

说,我有以下情况:

一个通用超类:

package com.cinefms.apitester.springmvc.crawlers;

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”是方法“运行”,那么

m.getGenericReturnType();

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

m.getReturnType();

给了我“TestGenericsInterface”(也没有帮助)。我一直在看“org.javaruntype”库...但我似乎无法弄明白。

有人可以解释一下吗?

谢谢!

3 个答案:

答案 0 :(得分:0)

感谢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];

我更倾向于在代码中使用前一种解决方案。

答案 1 :(得分:0)

您可以使用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

答案 2 :(得分:0)

TypeTools是另一种选择:

Class<?> t = TypeResolver.resolveRawArgument(TestGenerics.class, TestGenericsSub.class);

结果如预期:

assert t == TestGenericsImpl.class;