Java泛型:泛型超类的子类化-子类是可重新定义的类型吗?

Java泛型:泛型超类的子类化-子类是可重新定义的类型吗?,java,generics,Java,Generics,我正在读莫卧儿的SCJP(第三版)(我见过的最好的SCJP书),在第727页,它说: class MyIntList extends ArrayList <Integer> {} // A reifiable subclass 类MyIntList扩展了ArrayList{}//一个可重新定义的子类 现在我只是有点困惑。我知道该子类是非泛型类型,但由于它扩展了ArrayList,参数化的将最终被删除,并且该子类将继承其超类的属性,为什么该子类MyIntList是可修改类型?因

我正在读莫卧儿的SCJP(第三版)(我见过的最好的SCJP书),在第727页,它说:

class MyIntList extends ArrayList <Integer> {} // A reifiable subclass  
类MyIntList扩展了ArrayList{}//一个可重新定义的子类

现在我只是有点困惑。我知道该子类是非泛型类型,但由于它扩展了ArrayList,参数化的将最终被删除,并且该子类将继承其超类的属性,为什么该子类MyIntList是可修改类型?

因为
MyIntList
的每个实例都是
数组
,您可以使用反射找出下限/上限


如果您说
类MyNumberList扩展了ArrayList{…}
,您仍然可以找到边界,但不完全是Java语言规范中
MyNumberList
的特定实例的
T

4.7可偿还类型

由于某些类型信息在编译过程中被擦除,因此并非所有类型在运行时都可用。在运行时完全可用的类型称为可恢复类型。当且仅当下列条件之一成立时,类型才可重新定义:

  • 它引用非泛型类型声明
  • 它是一种参数化类型,其中所有类型参数都是无界通配符(§4.5.1)
  • 这是一种原始类型(§4.8)
  • 它是一种基本类型(§4.2)
  • 它是一种数组类型(§10.1),其组件类型是可修改的

泛型类型在ArrayList编译期间被擦除,但在MyIntList编译期间不会被擦除。因此,在运行时,您可以通过调用
MyIntList.class.getGenericSuperclass()
并分析返回的对象来发现MyIntList扩展了ArrayList


之所以可能,是因为MyIntList本身不是泛型的,而是扩展了ArrayList的具体实例化。因此,这些信息只能存储在MyIntList的类对象中(使用上述方法可以从中访问)。

但是参数化的erased@yapkm01:没有。泛型类型的特定参数化的非泛型子类型没有删除该参数化。@yapkm01建立直觉的一种方法是考虑实例。如果您有一个
ArrayList
的实例,您不知道
t
是什么。但是
MyIntList
的每个实例始终是一个
ArrayList
。换句话说,Java不会创建与
ArrayList
对应的新
类。但是参数类型被烘焙到
MyIntList
类中。在这种情况下,这种区别有什么关系?很明显,
new MyIntList().getClass()==MyIntList.class
不会丢失任何信息(因为它还能是什么?)——那么,人们是否正式地将“reifiable”一词指定给它有关系吗?你似乎认为在这种情况下,
MyIntList
将在运行时删除其超类参数
。事实并非如此。泛型类的具体子类保留其超类泛型参数的类型信息。这使得一些工具、测试等可以根据受限列表编写成为可能。