Java泛型 - 如何破解"Enum>"?

如下內容翻譯自連接內容其中一段章節:java

  • How do I decrypt "Enum<E extends Enum<E>>"?
Enum<E>僅容許它的子類 Color extends Enum<Color>去具現化它,而且 Color繼承了 Enum<Color>中一些有用的方法,而這些方法是接收或返回 Color類型的參數的。

public abstract class Enum<E extends Enum<E>> {
    ...
}

Enum類是Java內全部枚舉類型的通用基礎類。例如enum Color {}會被編譯成class Color extends Enum<Color>Enum<E>泛型基類存在的目的是爲全部枚舉類型提供基礎的方法及功能spa

如下是Euum類的骨架:翻譯

public abstract class Enum< E extends Enum<E>> implements Comparable<E>, Serializable { 
  private final String name; 
  public  final String name() { ... }
  private final int ordinal; 
  public  final int ordinal() { ... }

  protected Enum(String name, int ordinal) { ... }

  public String           toString() { ... } 
  public final boolean    equals(Object other) { ... } 
  public final int        hashCode() { ... } 
  protected final Object  clone() throws CloneNotSupportedException { ... } 
  public final int        compareTo( E o) { ... }

  public final Class<E> getDeclaringClass() { ... } 
  public static <T extends Enum<T>> T valueOf(Class<T> enumType, String name) { ... } 
}

如下是實際使用中的enum Color:設計

enum Color {RED, BLUE, GREEN}

Java編譯器會將它編譯成:code

public final class Color extends Enum<Color> { 
  public static final Color[] values() { return (Color[])$VALUES.clone(); } 
  public static Color valueOf(String name) { ... }
  private Color(String s, int i) { super(s, i); }

  public static final Color RED; 
  public static final Color BLUE; 
  public static final Color GREEN;

  private static final Color $VALUES[];

  static { 
    RED = new Color("RED", 0); 
    BLUE = new Color("BLUE", 1); 
    GREEN = new Color("GREEN", 2); 
    $VALUES = (new Color[] { RED, BLUE, GREEN }); 
  } 
}

Color繼承了全部Enum<Color>所實現了的方法。compareTo方法就是其中之一。
能夠看到,Color.compareTo接收的參數應該也必須是Color類型實例。爲了讓這可以實現,Enum設置了泛型<E>並在Enum.compareTo實現中以E類型的實例做爲方法參數。繼承

clipboard.png

做爲繼承的結果,Color類型從Enum<Color>中派生出來的compareTo方法實際上接收的參數就是Color類型的實例,這完美地達成了設計目標。ip

若是咱們繼續深刻解剖類聲明Enum<E extends Enum<E>>,咱們能夠看到它有如下幾方面的意義:get

第一,Enum的泛型E的上界爲Enum自身。這確保了只有Enum的子類才被容許成爲泛型參數。(理論上,Enum能夠被它本身具現化,例如Enum<Enum>,但這沒有意義,而且很難想象這會有對應的應用場景。)編譯器

第二,泛型E的上界被進一步限定爲extends Enum<E>,這確保了Enum<子類A>Enum<子類A>的子類A的繼承關係必定知足子類A extends Enum<子類A>。相似子類A extends Enum<子類B>這樣的聲明會被編譯器拒絕,由於這個聲明並不匹配泛型參數的上界。hash

第三,基於Enum被設計爲泛型,這意味着Enum中的某些方法的方法參數返回類型未知類型(又或者說是依賴於某未知類型)。而根據E extends Enum<E>,咱們能夠知道E確定會是Enum的子類。因此,在具象化類型Enum<某具體類>中,這些泛型方法的參數返回類型就會被編譯器轉換爲某具體類型。(compareTo就是一個例子)。總結來講,E extends Enum<E>保證了每一個Enum<E>的子類中都可以接收並返回該子類類型E

相關文章
相關標籤/搜索