Java反射:获取实现的通用接口的具体类型

发布于 2024-12-10 20:19:49 字数 222 浏览 4 评论 0原文

假设我有一个如下所示的类

public class AtomEntryHandler implements ConsumingHandler<AtomEntry>
{
...
}

是否可以从 AtomEntryHandler.class 的类对象获取类对象 AtomEntry.class ?

我以为不可能,因为删除了,但朋友说可以。

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 ?

I didn't think it was possible due to erasure, but a friend said it is.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

虚拟世界 2024-12-17 20:19:49

您可以获得接口和直接子类的泛型类型,但仅限于具体实现。例如,如果您有一个 List 实例,则由于类型擦除,您无法知道它被参数化的内容。如果类定义包含编译时已知的参数化类型(例如,class StringList extends List),那么您可以检索该信息。

ParameterizedType pt = (ParameterizedType)AtomEntryHandler.class.getGenericInterfaces()[0];
Class atomEntryClass = (Class)pt.getActualTypeArguments()[0];

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 can retrieve that information.

ParameterizedType pt = (ParameterizedType)AtomEntryHandler.class.getGenericInterfaces()[0];
Class atomEntryClass = (Class)pt.getActualTypeArguments()[0];
萌辣 2024-12-17 20:19:49

我无法找到一种方法来确定接口实现情况下的基本类型参​​数(这并不意味着没有)。但这已经很接近了。

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

结果:
类 java.lang.Integer

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

污味仙女 2024-12-17 20:19:49

如果您碰巧知道 ConsumingHandlerAtomEntryHandler 实现的唯一接口,并且您碰巧知道它只需要一个类型参数,您可以这样做:

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"
    }
}

否则,您可以四处看看在 getGenericInterfaces() 及其 actualTypeArguments 中,直到找到与您要查找的内容类似的内容。

但是,如果您发现自己需要在实际代码中执行此操作,则要么您的设计中可能出现严重错误,要么您正在编写一些疯狂的天才模拟对象库,并且您不应该需要我们来回答这些问题。

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:

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.

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.

烈酒灼喉 2024-12-17 20:19:49

这里有一篇博客文章详细介绍了它:Reflecting Generics< /代码>

There is a blog post that goes over it in detail here: Reflecting Generics.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文