[英]What is Identity and state of “java.lang.Enum” type objects in java?
[英]Why can't I recur in a java java.lang.Enum generic type definition?
這是一個學術問題,旨在更好地理解 generics 在這種情況下的行為。
Enum
類型被描述為“所有 Java 語言枚舉類型的公共基礎 class”。 它的定義是:
public abstract class Enum<E extends Enum<E>>
implements Comparable<E>, Serializable {
}
現在,我可以用這個定義定義一個字段:
public class MyClass {
public Enum<MyEnum> field;
}
一切都好。 現在,更進一步。 由於Enum<MyEnum>
顯然等同於MyEnum
這會讓我相信根據定義我也可以寫:
public class MyClass {
public Enum<Enum<MyEnum>> field;
}
但是現在編譯器實際上阻止了我: Type parameter 'java.lang.Enum' is not within its bound; should extend 'java.lang.Enum<MyEnum>>
Type parameter 'java.lang.Enum' is not within its bound; should extend 'java.lang.Enum<MyEnum>>
,因為它仍然滿足: E extends Enum<E>
。 當然,您不允許這種重復(或者可能更好,招致)構造的原因有很多,但是給定的原因對我來說確實是錯誤的。
另一方面,如果我要像這樣定義 class (類似於Enum
的定義)
public class Wrapper<T extends Number> {
}
我可以寫一個 class:
public class MyClass {
// satisfies the upper bound
public Wrapper<Integer> field1;
// also satisfies the upper bound
public Wrapper<Number> field2;
}
我是否忽略了某些東西,或者我的分析是否被誤導了?
我認為這是一個學術問題。 您實際上並沒有編寫這樣的代碼,您只是想更好地理解語言,對嗎? 因為在實際代碼中,您當然會簡單地編寫:
public MyEnum myField;
本着這種精神——
由於
Enum<MyEnum>
顯然等同於MyEnum
...
它們不是等價的。 MyEnum
是Enum<MyEnum>
的子類。 自動生成的 class 類似於:
public final class MyEnum extends Enum<MyEnum> {
...
}
這意味着您不能繼續使用Enum<Enum<MyEnum>>
擴展聲明。 如果你願意,你可以這樣寫:
public Enum<? extends Enum<MyEnum>> field;
那將編譯,遞歸的可能性到此為止。
我對 T 中的上限
X
的理解T extends X
,它包括X
及其子類。 所以Enum<Enum>
應該被允許,但它不是。
讓我們看看E
到底是什么,這里的E
:
public abstract class Enum<E extends Enum<E>>
當您編寫Enum<Enum<MyEnum>>
時, E
是Enum<MyEnum>
。 這個E
是否匹配約束E extends Enum<E>
? 我們需要將E
替換為Enum<MyEnum>
。
E extends Enum<E>?
^ ^
Enum<MyEnum> extends Enum<Enum<MyEnum>>?
^^^^^^^^^^^^ ^^^^^^^^^^^^
現在讓我們回答幾個相關但略有不同的問題:
MyEnum
是否擴展Enum<MyEnum>
? 是的。 我上面列出的自動生成的代碼表明情況就是如此。
Enum<MyEnum>
是否擴展Enum<MyEnum>
? 是的。 正如您在Number
示例中正確描述的那樣,就extends
關鍵字而言, class 被認為是其自身的子類。
現在我們現在關心的問題是: Enum<MyEnum>
是否擴展了Enum<Enum<MyEnum>>
? 不,它沒有。 這是您嘗試工作的代碼需要保持的關系。 它不成立,這就是您的代碼無法編譯的原因。
使用Enum<Enum<MyEnum>>
,它使E
等於Enum<MyEnum>
。
因此,綁定E extends Enum<E>
要求Enum<MyEnum>
必須擴展Enum<Enum<MyEnum>>
,但它沒有,因此被編譯器拒絕。
請記住, Enum
是enum
的隱式超類。
當您編寫enum MyEnum {... }
時,您得到的實際上是class MyEnum extends Enum<MyEnum> {... }
。
這使得E
等於MyEnum
。
因此,綁定E extends Enum<E>
要求MyEnum
必須擴展Enum<MyEnum>
,它確實如此,因此編譯器很高興。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.