这是场景
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();
为什么?
有没有办法通过父类型引用?
这条线
Parent<MyClass1> p = new Child();
无法编译,因为
Child
类已将类型参数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>
。
这就是泛型的工作原理。您已明确声明类
Child
是 Parent<MyClass2>
的子类。但 Parent<MyClass2>
不是 Parent<MyClass1>
的子类,因此 Child 不是 Parent<MyClass1>
的子类。
将构造函数调用更改为
Parent<? extends MyClass1> p = new Child();
你所说的是一个叫做协方差的概念。在您的实现中,
MyClass1 extends MyClass2
并不意味着Parent<MyClass1> extends Parent<MyClass2>
,因此Parent<MyClass1> p = new Child();
无法编译。
您必须在实例化中明确提及这一点:
Parent<? extends MyClass1> p = new Child();
所以现在你告诉编译器
T
是MyClass1
的子类,所以编译器放弃它。
通过您的
Child
类定义,您声明通用 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>{}
这对于 jpa 实体可能吗?