簡體   English   中英

為什么我不能在 java java.lang.Enum 泛型類型定義中重復出現?

[英]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 ...

它們不是等價的。 MyEnumEnum<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>>時, EEnum<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>> ,但它沒有,因此被編譯器拒絕。


請記住, Enumenum的隱式超類。

當您編寫enum MyEnum {... }時,您得到的實際上是class MyEnum extends Enum<MyEnum> {... }

這使得E等於MyEnum

因此,綁定E extends Enum<E>要求MyEnum必須擴展Enum<MyEnum> ,它確實如此,因此編譯器很高興。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM