Sja*_*aak 0 java generics enums
这是一个学术问题,旨在更好地理解泛型在这种情况下的行为。
该Enum类型被描述为“所有 Java 语言枚举类型的公共基类”。它的定义是:
public abstract class Enum<E extends Enum<E>>
implements Comparable<E>, Serializable {
}
Run Code Online (Sandbox Code Playgroud)
现在,我可以用这个定义定义一个字段:
public class MyClass {
public Enum<MyEnum> field;
}
Run Code Online (Sandbox Code Playgroud)
一切都很好。现在,更进一步。因为Enum<MyEnum>显然等同于MyEnum这会让我相信根据定义我也可以写:
public class MyClass {
public Enum<Enum<MyEnum>> field;
}
Run Code Online (Sandbox Code Playgroud)
但是现在编译器实际上阻止了我:Type parameter 'java.lang.Enum' is not within its bound; should extend 'java.lang.Enum<MyEnum>>它根据定义进行操作,因为它仍然满足:E extends Enum<E>。当然,您不允许这种重复(或者可能更好,发生)构造的原因有很多,但给出的一个对我来说确实是错误的。
另一方面,如果我要定义一个这样的类(类似于 的定义Enum)
public class Wrapper<T extends Number> {
}
Run Code Online (Sandbox Code Playgroud)
我将能够编写一个类:
public class Wrapper<T extends Number> {
}
Run Code Online (Sandbox Code Playgroud)
我是忽略了什么还是我的分析被误导了?
我认为这是一个学术问题。你实际上并不是在写这样的代码,你只是想更好地理解语言,对吧?因为在实际代码中,您当然会简单地编写:
public MyEnum myField;
Run Code Online (Sandbox Code Playgroud)
本着这种精神——
因为
Enum<MyEnum>显然等价于MyEnum...
它们不是等价的。MyEnum是一个子类的Enum<MyEnum>。自动生成的类是这样的:
public final class MyEnum extends Enum<MyEnum> {
...
}
Run Code Online (Sandbox Code Playgroud)
这意味着您不能继续使用Enum<Enum<MyEnum>>. 如果你愿意,你可以这样写:
public Enum<? extends Enum<MyEnum>> field;
Run Code Online (Sandbox Code Playgroud)
那将编译,并且递归的可能性到此为止。
我理解的上限是什么
X在T extends X它包括X和它的子类。所以Enum<Enum>应该被允许,但事实并非如此。
让我们来看看究竟是什么E,E从这里:
public abstract class Enum<E extends Enum<E>>
Run Code Online (Sandbox Code Playgroud)
当你写Enum<Enum<MyEnum>>,E是Enum<MyEnum>。这E与约束匹配E extends Enum<E>吗?我们需要替换E使用Enum<MyEnum>。
E extends Enum<E>?
^ ^
Enum<MyEnum> extends Enum<Enum<MyEnum>>?
^^^^^^^^^^^^ ^^^^^^^^^^^^
Run Code Online (Sandbox Code Playgroud)
现在让我们回答几个相关但略有不同的问题:
是否MyEnum延长Enum<MyEnum>?是的。我上面列出的自动生成的代码显示了这种情况。
是否Enum<MyEnum>延长Enum<MyEnum>?是的。正如您在Number示例中正确描述的那样,就extends关键字而言,类被认为是其自身的子类。
现在我们现在关心的问题是:是否Enum<MyEnum>扩展Enum<Enum<MyEnum>>?不,它没有。这是为了让您尝试工作的代码需要保持的关系。它不成立,这就是您的代码无法编译的原因。
| 归档时间: |
|
| 查看次数: |
71 次 |
| 最近记录: |