【问题标题】:How to properly load a class which implements a parameterized interface?如何正确加载实现参数化接口的类?
【发布时间】:2012-09-14 09:40:36
【问题描述】:

Class<List>Class<List<?>>Class<List<Anything> 实际上指的是同一个Class

如果我有

class MyClass implements List<SomeClass> {
    // ...
}

然后我就可以写了

Class<? extends List<SomeClass>> myClass = MyClass.class;

这样我就可以写了

List<SomeClass> myInstance = myClass.newInstance();

诀窍是我想通过反射使用ClassLoader.loadClass 加载这个类,并且仍然用相同的类型声明myClass。正确/最简单的方法是什么?

我想要一个不会引发编译警告并且不需要@SuppressWarnings 的解决方案(这可能意味着对超级类型进行运行时检查,例如更强大的Class.asSubclass 版本)。

【问题讨论】:

  • 确实这似乎是同一个问题......并且没有一个一般的答案:(
  • 所以你有这种要求只是因为你不喜欢抑制警告,或者你需要防弹类型检查?
  • 出现警告是有原因的(这里需要未经检查的强制转换),所以我的问题是如何抑制它们(这在逻辑上需要运行时检查)

标签: java reflection


【解决方案1】:
 public Class<?> loadClass(String name) throws ClassNotFoundException

因为它返回 Class&lt;?&gt; 泛型类 your type information is lost here。因此,您必须将类型转换为所需的类型。

【讨论】:

  • 正如我在下面的评论中所说,类型信息仍然存在。在运行时检查它并避免警告似乎很困难。通常你可以通过使用Class.asSubclass(它也执行运行时检查)来避免类型转换,但它不适用于泛型。
【解决方案2】:

当你编译一个带有泛型签名的类时,所有关于泛型的信息都会丢失。对于 jvm,它就像:

class MyClass implements List {
    // ...
}

如果你用javap 反编译一个类,你可以检查这个:你不会在那里看到通用的东西。泛型主要用于编译时检查。因此,当您使用反射加载一个类时,您必须将其转换为您的通用版本。

【讨论】:

  • 这是一个错误的信念,只有一部分通用信息丢失了,但编译依赖类所需的一切都保留了。如果您使用MyClass.class.getGenericInterfaces(),您将能够看到完整的List&lt;SomeClass&gt;
  • @DidierL:哦,对不起,我不知道那些方法。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-09-28
  • 2022-01-23
  • 1970-01-01
  • 2018-05-04
  • 1970-01-01
  • 1970-01-01
  • 2016-02-15
相关资源
最近更新 更多