如何从父泛型引用子泛型?
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
。如果您希望 MyClass1
和 MyClass2
都被接受为 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 Child
是 Parent<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>
,即使 MyClass2
是 MyClass1
。那是因为 Java 的泛型是不变的。
在使用 MyClass1
时使其编译的解决方案是使用有界通配符。
Parent<? extends MyClass1> p = new Child();
通配符允许MyClass2
和MyClass1
之间的关系扩展到Parent<MyClass2>
和Parent<? extends MyClass1>
。
你说的是一个叫做协方差的概念。在您的实现中 MyClass1 extends MyClass2
并不意味着 Parent<MyClass1> extends Parent<MyClass2>
所以 Parent<MyClass1> p = new Child();
不编译。
您必须在实例化中明确提及这一点:
Parent<? extends MyClass1> p = new Child();
所以现在你告诉编译器 T
是 MyClass1
的子类所以编译器放手。
场景如下
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
。如果您希望 MyClass1
和 MyClass2
都被接受为 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 Child
是 Parent<MyClass2>
的子 class。但是 Parent<MyClass2>
不是 Parent<MyClass1>
的子 class,因此 Child 不是 Parent<MyClass1>
.
将您的构造函数调用更改为
Parent<? extends MyClass1> p = new Child();
这一行
Parent<MyClass1> p = new Child();
无法编译,因为 Child
class 已将类型参数 T
定义为 MyClass2
。所有 Child
个对象都是 Parent<MyClass2>
个对象,Parent<MyClass2>
不是 Parent<MyClass1>
,即使 MyClass2
是 MyClass1
。那是因为 Java 的泛型是不变的。
在使用 MyClass1
时使其编译的解决方案是使用有界通配符。
Parent<? extends MyClass1> p = new Child();
通配符允许MyClass2
和MyClass1
之间的关系扩展到Parent<MyClass2>
和Parent<? extends MyClass1>
。
你说的是一个叫做协方差的概念。在您的实现中 MyClass1 extends MyClass2
并不意味着 Parent<MyClass1> extends Parent<MyClass2>
所以 Parent<MyClass1> p = new Child();
不编译。
您必须在实例化中明确提及这一点:
Parent<? extends MyClass1> p = new Child();
所以现在你告诉编译器 T
是 MyClass1
的子类所以编译器放手。