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

问题描述 投票:0回答:5

这是场景

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();

为什么?

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

java generics inheritance
5个回答
3
投票

这条线

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>


3
投票

这就是泛型的工作原理。您已明确声明类

Child
Parent<MyClass2>
的子类。但
Parent<MyClass2>
不是
Parent<MyClass1>
的子类,因此 Child 不是
Parent<MyClass1>
的子类。

将构造函数调用更改为

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

1
投票

你所说的是一个叫做协方差的概念。在您的实现中,

MyClass1 extends MyClass2
并不意味着
Parent<MyClass1> extends Parent<MyClass2>
,因此
Parent<MyClass1> p = new Child();
无法编译。

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

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

所以现在你告诉编译器

T
MyClass1
的子类,所以编译器放弃它。


0
投票

通过您的

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>{}

0
投票

这对于 jpa 实体可能吗?

© www.soinside.com 2019 - 2024. All rights reserved.