java Java反射:获取实现的通用接口的具体类型
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/7844610/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Java reflection: Get concrete type of implemented generic interface
提问by ekj
Say I have a class like the following
说我有一个像下面这样的课程
public class AtomEntryHandler implements ConsumingHandler<AtomEntry>
{
...
}
Is it possible to get the class object AtomEntry.class from the class object of AtomEntryHandler.class ?
是否可以从 AtomEntryHandler.class 的类对象中获取类对象 AtomEntry.class ?
I didn't think it was possible due to erasure, but a friend said it is.
由于擦除,我不认为这是可能的,但一个朋友说是。
回答by Chris Hannon
You can get the generic type for both interfaces and direct subclasses, but only for the concrete implementation. For example, if you have a List<T>
instance, you have no way of knowing what it's been parameterized to because of type erasure. If the class definition includes parameterized types that are known at compile time (for example, class StringList extends List<String>
) then you canretrieve that information.
您可以获得接口和直接子类的泛型类型,但仅限于具体实现。例如,如果您有一个List<T>
实例,由于类型擦除,您无法知道它被参数化的内容。如果类定义包含编译时已知的参数化类型(例如,class StringList extends List<String>
),则您可以检索该信息。
ParameterizedType pt = (ParameterizedType)AtomEntryHandler.class.getGenericInterfaces()[0];
Class atomEntryClass = (Class)pt.getActualTypeArguments()[0];
回答by Alex Gitelman
I could not figure a way to determine base type parameter in case of interface implementation (which does not mean there is none). But this is as close as it gets to it.
在接口实现的情况下,我无法找到确定基类型参数的方法(这并不意味着没有)。但这已经很接近了。
import java.lang.reflect.*;
public class Foo {
static class Bar<T> {
}
static class SubBar extends Bar<Integer> {
}
public static void main(String argv[]) {
ParameterizedType pt = (ParameterizedType)SubBar.class.getGenericSuperclass();
Type[] t = pt.getActualTypeArguments();
for (int i=0;i<t.length;i++) {
System.out.println(t[i]);
}
}
}
Result:
class java.lang.Integer
结果:
class java.lang.Integer
回答by David Moles
If you happen to know ConsumingHandler
is the only interface AtomEntryHandler
implements, and you happen to know it takes just one type argument, you can do this:
如果你碰巧知道ConsumingHandler
是唯一的接口AtomEntryHandler
实现,并且碰巧知道它只需要一个类型参数,你可以这样做:
interface ConsumingHandler<T> {}
class AtomEntry {}
class AtomEntryHandler implements ConsumingHandler<AtomEntry>
{
public static void main( String[] args )
{
Type[] interfaces = AtomEntryHandler.class.getGenericInterfaces();
ParameterizedType firstInterface = (ParameterizedType) interfaces[0];
Class c = (Class) firstInterface.getActualTypeArguments()[0];
System.out.println(c.getName()); // prints "AtomEntry"
}
}
Otherwise, you can poke around in getGenericInterfaces()
and their actualTypeArguments
until you find something that looks like what you're looking for.
否则,您可以在getGenericInterfaces()
和他们的周围闲逛,actualTypeArguments
直到找到看起来像您正在寻找的东西。
But if you find yourself needing to do this in real code, either something's probably gone badly wrong in your design, or you're writing some mad genius mock object library and you shouldn't need us to answer these questions.
但是,如果您发现自己需要在实际代码中执行此操作,则可能是您的设计中出现了严重错误,或者您正在编写一些疯狂的天才模拟对象库,而您不应该需要我们来回答这些问题。
回答by Bringer128
There is a blog post that goes over it in detail here: Reflecting Generics
.
这里有一篇博客文章详细介绍了它:Reflecting Generics
。