为什么可以';是否在java.lang.Enum泛型类型定义中重复?
这是一个学术问题,旨在更好地理解泛型在这种情况下的行为为什么可以';是否在java.lang.Enum泛型类型定义中重复?,java,generics,enums,Java,Generics,Enums,这是一个学术问题,旨在更好地理解泛型在这种情况下的行为 Enum类型被描述为“所有Java语言枚举类型的公共基类”。其定义是: 公共抽象类枚举 实现可比较的、可序列化的{ } 现在,我可以用这个定义定义一个字段: 公共类MyClass{ 公共枚举字段; } 都很好。现在,更进一步。因为Enum显然等同于MyEnum,这让我相信,根据定义,我也可以写: 公共类MyClass{ 公共枚举字段; } 但现在编译器实际上阻止了我:类型参数'java.lang.Enum'不在其范围内;应该扩展“j
Enum
类型被描述为“所有Java语言枚举类型的公共基类”。其定义是:
公共抽象类枚举
实现可比较的、可序列化的{
}
现在,我可以用这个定义定义一个字段:
公共类MyClass{
公共枚举字段;
}
都很好。现在,更进一步。因为Enum
显然等同于MyEnum
,这让我相信,根据定义,我也可以写:
公共类MyClass{
公共枚举字段;
}
但现在编译器实际上阻止了我:类型参数'java.lang.Enum'不在其范围内;应该扩展“java.lang.Enum>
,因为它仍然满足:E扩展Enum
。当然,有各种各样的理由为什么你不允许这种重复的(或者更好的,招致的)构造,但是给出的那个确实让我觉得不对
另一方面,如果我定义这样一个类(类似于Enum
的定义)
公共类包装器{
}
我将能够编写一个类:
公共类MyClass{
//满足上界
公共领域1;
//也满足上界
公共领域2;
}
是我忽略了什么,还是我的分析被误导了?我认为这是一个学术问题。实际上,您并不是在编写这样的代码,您只是想更好地理解这种语言,对吗?因为在实际代码中,您当然只需编写:
public MyEnum myField;
本着这种精神-
因为Enum
显然等同于MyEnum
它们不是等价物MyEnum
是Enum
的子类。自动生成的类类似于:
public final class MyEnum extends Enum<MyEnum> {
...
}
编写Enum
时,E
是Enum
。此E
是否与约束E扩展枚举
匹配?我们需要用Enum
替换E
E扩展枚举?
^ ^
枚举扩展枚举?
^^^^^^^^^^^^ ^^^^^^^^^^^^
现在让我们回答几个相关但微妙不同的问题:
- MyEnum是否扩展了Enum?对我在上面列出的自动生成代码显示了这种情况
是否扩展Enum
?对正如您在Enum
示例中正确描述的,就Number
关键字而言,类被视为自身的子类extends
- 现在我们关心的问题是:
是否扩展了Enum
?不,没有。这是您尝试工作的代码需要保持的关系。它不起作用,这就是你的代码不能编译的原因Enum
Enum
,它使E
等于Enum
绑定的E扩展了Enum
,因此要求Enum
必须扩展Enum
,但它没有扩展,因此被编译器拒绝
请记住,
Enum
是Enum
的隐式超类
当您编写enum MyEnum{…}
时,您得到的实际上是类MyEnum扩展了enum{…}
这使得E
等于MyEnum
绑定的
E扩展了Enum
因此需要MyEnum
必须扩展Enum
,编译器会很高兴的。如果我误解了这个问题,很抱歉,public MyEnum field
可以为您工作吗?“我可以用这个定义定义定义一个字段:public Enum field
”——为什么?既然MyEnum扩展了Enum
,而且将是唯一一个这样做的类,为什么不将其定义为public MyEnum field
,这与实际解决方案无关。这是为了更好地理解语言。是的。。这是学术性的。没有。。我肯定不会这样写代码:)。但我参与了构建一个需要匹配类型的注释处理器。我们应该能够涵盖所有的场景。这就是为什么我想理解为什么我的推理会出错。我需要仔细考虑你的答案。假设一个类:公共类包装器{}
。我可以创建这样一个字段:public class MyType{public Wrapper field;}
对吗?上限也包括Number
,而不使用通配符。我扩展了我的示例,只是为了说明这是一个学术问题。我知道MyEnum
是Enum
的一个子类,但它仍然满足上限,对吧。它包括(因此我的例子是Number
)。所以我的意思是:Enum
的参数是Enum
或rawEnum
。我在T中对上界X的理解扩展了X,它包括X及其子类。所以Enum
应该被允许,但它不是。在这里,我不明白它与我的Number
示例有何不同。你的答案非常清楚,它确实帮了我很多忙。非常感谢您投入的时间。虽然对我来说,aha的时刻到来了,答案是上面的@Andreas。混淆的部分是扩展
绑定。毕竟,(原始)Enum
在E扩展Enum
的范围内。但破坏它的是泛型类型参数X
Enum
,我需要一些帮助才能实现这一点。你在关系T扩展了SomeType
,T
永远不能等于SomeType
。它必须是:SomeType<
public final class MyEnum extends Enum<MyEnum> {
...
}
public Enum<? extends Enum<MyEnum>> field;
public abstract class Enum<E extends Enum<E>>
E extends Enum<E>?
^ ^
Enum<MyEnum> extends Enum<Enum<MyEnum>>?
^^^^^^^^^^^^ ^^^^^^^^^^^^