2014-11-09 151 views
0

我知道我正在尝试做的事情对于纯java来说并不是真的可行 - 只有当我查看调试信息时才有可能。无论如何我都不会编译,因为我的spring mvc会停止工作。如何确定泛型超类的特定子类的ACTUAL返回类型?

这么说,我有以下情况:

一个通用超:

包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 { 

} 

日食是完全没有搞清楚是的TestGenericsSub.get()应返回的TestGenericsImpl实例......即使没有源可用。

但我怎么可能在运行时自己弄清楚这一点?

如果 “M” 是方法 “运行”,然后

m.getGenericReturnType(); 

将返回 “T”(没有用),而:

m.getReturnType(); 

给我 “TestGenericsInterface”(也未有用)。我一直在看“org.javaruntype”库...但我似乎无法弄清楚。

有人可以解释吗?

谢谢!

+0

你不能,在一般情况下,判断ACTUAL返回类型的方法,而不检查方法中的代码(通用与否)。最好你可以确定方法声明中指定的FORMAL返回类型(使用适当的泛型swizzle),但该方法总是可以返回该类型的子类。 – 2014-12-04 20:29:06

回答

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 
+0

是的,这几乎是我一直在寻找的东西。我发现在org.javaruntime中很难做到 - 在那里,我可以获得所有必要的信息,但是我必须自己解决超类的泛型变量 - 真的有点痛苦。感谢指针! – rmalchow 2014-11-09 15:29:39

0

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

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

我会在代码中更喜欢前者的解决方案。

+0

嗨。事情是,我实际上在对其他人的代码进行反省。特别是,我试图从Spring MVC控制器此信息,: \t https://github.com/rmalchow/spring-api-tester \t ,所以我不能实际控制的代码。一般来说,我同意。 – rmalchow 2014-11-09 15:26:29

0

TypeTools是另一种选择:

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

如预期的结果:

assert t == TestGenericsImpl.class;