【问题标题】:What are the exceptions to type erasure in Java?Java中类型擦除的例外是什么?
【发布时间】:2012-08-06 05:23:41
【问题描述】:

我在网上的某些地方看到它提到,在某些情况下,可以使用反射 API 来获取有关泛型数据类型的信息,我认为这些信息会因类型擦除而丢失。

我正在寻找类型擦除不完整的情况的完整列表,即仍然可以通过反射访问某些内容。可以获取泛型类型的示例和相关反射代码的良好列表将非常好。

更新 http://tutorials.jenkov.com/java-reflection/generics.html 正是我正在寻找的示例。

【问题讨论】:

标签: java generics reflection type-erasure


【解决方案1】:

我认为归根结底是这样的:

  • 没有对象实例存储任何类型信息。

  • 然而,这些类保留了它们的所有泛型签名(否则在编译时您无法进行任何泛型类型检查)

因此,使用反射,您可以读取给定类的泛型类型信息。

例子:

 class MyList extends ArrayList<MyObject>{}

 List<MyObject> x = new MyList();

Reflection 会告诉你这是一个 MyObject 的 List(因为这个信息被编译到了 MyList 类中)。

但是

List<MyObject> x = new ArrayList<MyObject>();

Reflection 不会告诉你任何有用的信息(因为 ArrayList class 对 MyObject 一无所知)。

【讨论】:

  • +1 保留任何通用信息的原因是为了让javac 编译器完成它的工作。例如您必须能够使用已正确编译的代码中的泛型来编译代码。
  • 除了超类之外,非私有字段类型中的泛型,以及方法参数和返回类型,也都存在,用于类型检查。
  • 是的,所有这些都是类定义的一部分。上面的示例并非详尽无遗。但请注意,在所有这些情况下,泛型可用于字段/参数/返回类型定义(签名),而不是分配给它们的任何对象的实际运行时值..跨度>
【解决方案2】:

一般的想法是,如果您创建一个命名或匿名类,该类是泛型类型的子类,类型参数具有特定类型,那么该子类不是泛型的,并且不受类型擦除的影响。假设您可以获取子类的 Class 对象,您可以对该对象使用反射来找出参数类型。

仔细想想,这并不是擦除规则的真正“例外”。相反,它是通过显式具体化来安排所讨论的类不是通用的。

【讨论】:

  • "找出参数类型是什么"不,您正在找出它扩展的超类的类型参数。
猜你喜欢
  • 2016-04-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-29
相关资源
最近更新 更多