转载

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

以下内容翻译自链接内容其中一段章节:

  • How do I decrypt "Enum<E extends Enum<E>>"?
public abstract class Enum<E extends Enum<E>> {
    ...
}

Enum 类是Java内所有枚举类型的通用基础类。例如 enum Color {} 会被编译成 class Color extends Enum<Color>Enum基类 存在的目的是为这些所有枚举类型提供基础的方法及功能。

以下是 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编译器会将它编译成:

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类型的实例 作为方法参数。

Java泛型 - 如何破解&quot;Enum&lt;E extends Enum&lt;E&gt;&gt;&quot;?

而作为继承的结果, Color 类型从 Enum<Color> 中派生出来的 compareTo 方法实际上接收的参数就是 Color类型的实例 ,这完美地达成了设计目标。

如果我们继续深入解剖类声明 Enum<E extends Enum<E>> ,我们可以看到它有以下几方面的意义:

第一, Enum 的泛型 E 的上界为 Enum 自身。这确保了只有 Enum 的子类才被允许成为泛型参数。(理论上, Enum 可以被它自己具现化,例如 Enum<Enum> ,但这没有意义,并且很难想象这会有对应的应用场景。)

第二,泛型 E 的上界被进一步限定为 extends Enum<E> ,这确保了 Enum<子类A>Enum<子类A>的子类A 的继承关系一定满足 子类A extends Enum<子类A> 。类似 子类A extends Enum<子类B> 这样的声明是会被编译器拒绝的,因为这个声明并不匹配泛型参数的上界。

第三,基于 Enum 被设计为泛型,这意味着 Enum类 中的某些方法的 方法参数返回类型运行时未知类型 (又或者说是依赖于 某未知类型 )。而根据 E extends Enum<E> ,我们可以知道 E 肯定会是 Enum<?> 的子类。所以,在具象化类型 Enum<某具体类> 中,这些泛型方法的 参数返回类型 就会被 编译器 转换为 某具体类型 。( compareTo 就是一个例子)。总结来说, E extends Enum<E> 保证了每个 Enum<E> 的子类中都能够 接收并返回 该子类类型。

原文  https://segmentfault.com/a/1190000018395096
正文到此结束
Loading...