以下内容翻译自链接内容其中一段章节:
- 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>泛型基类
存在的目的是为所有枚举类型
提供基础的方法及功能。
以下是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类型的实例
作为方法参数。
作为继承的结果,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>
的子类中都能够接收并返回
该子类类型E
。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。