如何从父泛型引用子泛型?

how to have a reference to child generic type from a parent generic type?

场景如下

class MyClass1{

}

class MyClass2 extends MyClass1{

}

class Parent<T>{
 List<T> list;
}


class Child extends Parent<MyClass2>{
}

这不编译

Parent<MyClass1> p = new Child();

这样做

Parent<MyClass2> p = new Child();

为什么?

有没有办法通过父类型进行引用?

根据您的 Child class 定义,您声明通用 Parent 将接受的唯一类型是 MyClass2。如果您希望 MyClass1MyClass2 都被接受为 Parent 中的泛型,请执行以下操作:

class MyClass1{}
class MyClass2 extends MyClass1{}
class Parent<T extends MyClass1>
{ List<T> list; }
class Child<T extends MyClass1> extends Parent<T>{}

This is how generics works。您已经明确声明 class ChildParent<MyClass2> 的子 class。但是 Parent<MyClass2> 不是 Parent<MyClass1> 的子 class,因此 Child 不是 Parent<MyClass1>.

的子class

将您的构造函数调用更改为

Parent<? extends MyClass1> p = new Child();

这一行

Parent<MyClass1> p = new Child();

无法编译,因为 Child class 已将类型参数 T 定义为 MyClass2。所有 Child 个对象都是 Parent<MyClass2> 个对象,Parent<MyClass2> 不是 Parent<MyClass1>,即使 MyClass2MyClass1。那是因为 Java 的泛型是不变的。

在使用 MyClass1 时使其编译的解决方案是使用有界通配符。

Parent<? extends MyClass1> p = new Child();

通配符允许MyClass2MyClass1之间的关系扩展到Parent<MyClass2>Parent<? extends MyClass1>

你说的是一个叫做协方差的概念。在您的实现中 MyClass1 extends MyClass2 并不意味着 Parent<MyClass1> extends Parent<MyClass2> 所以 Parent<MyClass1> p = new Child(); 不编译。

您必须在实例化中明确提及这一点:

Parent<? extends MyClass1> p = new Child();

所以现在你告诉编译器 TMyClass1 的子类所以编译器放手。