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

相关文章
相关标签/搜索