Java 泛型嵌套在泛型中的类的泛型用法
即使这不是一个好的练习,我也想知道为什么 下面的代码没有编译,我真的不明白为什么Java 泛型嵌套在泛型中的类的泛型用法,java,generics,inner-classes,Java,Generics,Inner Classes,即使这不是一个好的练习,我也想知道为什么 下面的代码没有编译,我真的不明白为什么 假设我对小丑、王后和国王有一个抽象的定义: abstract class JokerA { //JokerA does things } abstract class QueenA<J extends JokerA> { //QueenA makes use of J class Princess { void receiveGift(Gift gift) {
假设我对小丑、王后和国王有一个抽象的定义:
abstract class JokerA {
//JokerA does things
}
abstract class QueenA<J extends JokerA> {
//QueenA makes use of J
class Princess {
void receiveGift(Gift gift) {
/* ... */
}
}
}
abstract class KingA<Q extends QueenA<?>> {
KingA(Q.Princess princess) {
Gift giftForPrincess = new Gift();
princess.receiveGift(giftForPrincess);
}
}
抽象类{
//乔凯拉做事
}
抽象类皇后{
//奎纳利用J
公主班{
无效接受礼品(礼品){
/* ... */
}
}
}
抽象类KingA>扩展了KingA{
金B(Q.公主){
超级(公主);//错误
}
}
错误是:
KingA(QueenA首先,这里只有一个类名为Princess
,它是QueenA.Princess
。没有QueenB.Princess
——如果您编写QueenB.Princess
,编译器只会理解它的意思是QueenA.Princess
。请注意,Princess
是QueenA
,一个泛型类,QueenA.Princess
也是一个泛型类(由QueenA
的参数参数化)。当它被参数化时,它看起来像QueenA.Princess
由于问题是类Princess
的两个值之间的兼容性,并且我们在上面提到了一个这样的类,因此唯一的兼容性问题是泛型类型参数。传递到super()的类型
被认为是Q.Princess
。但正如我们前面提到的,Princess
属于QueenA
,而不是QueenB
或Q
。因此编译器在编译时会自动将其重新写入QueenA.Princess
。问题是什么是东西
。基本上,问题是Q
是一个QueenA
Q
是一个绑定了QueenB
的类型变量。这意味着可以使用Q
作为QueenB
的X
作为满足QueenB
类型参数边界的任何类型的类(即扩展JokerB
)因此,我们不能假设关于X
的任何东西,除了它是JokerB
QueenB
的子类型,它扩展了QueenA
,这意味着Q
是QueenA
只是编译器打印出来表示未知类型的东西。因此,在这一点上,编译器已经发现Q.Pr乱伦真正的意思是皇后公主
然后将其传递给super()
,它是KingA
的构造函数。此类型参数的参数类型也被写入Q.Princess
(注意:这是KingA
的Q
,一个不同类型的参数;请不要混淆)。如果您按照上面相同的分析进行操作,您将看到编译器看到这个Q.Princess
实际上意味着QueenA.Princess
问题是,QueenA.Princess
是QueenA.Princess
的一个子类型吗?即第一个未知子类型
是否与第二个未知子类型
相同?(请记住泛型是不变的。)编译器只看这一点就会说,它不知道它们是否相同,因为两个未知类型肯定会不同,所以它们不兼容
你可能会说,等一下,你知道Q
是一个QueenA
对于某个未知类型X
,KingB
被声明为扩展KingA
,因此KingB
中的Q
对于特定对象的作用域与KingB
中的Q
的作用域相同是相同的,未知的X
在这两种情况下都是相同的。但这不适用于这里,因为不再考虑Q
。请记住,没有类型Q.Princess
。它所指的真正类型是QueenA.Princess
。QueenA.Princess
是在编译时计算出来的每个类的每个构造函数。一旦算出它是未知类型
,它就被固定为未知类型
,并且与类的类型参数Q
无关。因此这两个未知类型没有关系
您可以通过使用新的类型参数来解决此问题,而不是让编译器推断未知类型。然后,类型参数可以允许您连接该类型的不同用途,让编译器知道它们是同一类型。类似于以下内容:
abstract class KingA<J extends JokerA, Q extends QueenA<J>> {
KingA(Q.Princess princess) {
Gift giftForPrincess = new Gift();
princess.receiveGift(giftForPrincess);
}
}
abstract class KingB<J extends JokerB, Q extends QueenB<J>> extends KingA<J, Q> {
KingB(Q.Princess princess) {
super(princess);
}
}
抽象类KingA{
金卡(问公主){
礼品礼品Forprincess=新礼品();
公主。接受礼物(礼物或礼物);
}
}
抽象类KingB扩展了KingA{
金B(Q.公主){
超级(公主);
}
}
KingA(QueenA<capture<?>>.Princess) in KingA cannot be applied to (Q.Princess)
abstract class KingA<J extends JokerA, Q extends QueenA<J>> {
KingA(Q.Princess princess) {
Gift giftForPrincess = new Gift();
princess.receiveGift(giftForPrincess);
}
}
abstract class KingB<J extends JokerB, Q extends QueenB<J>> extends KingA<J, Q> {
KingB(Q.Princess princess) {
super(princess);
}
}