Recursive Type Bounds

How do I decrypt "Enum<E extends Enum<E>>"?

As a type that can only be instantiation for its subtypes, and those subtypes will inherit some useful methods, some of which take subtype arguments (or otherwise depend on the subtype).
The context in which " Enum<E extends Enum<E>> " appears is the declaration of the Enum class in package java.lang : 
public abstract class  Enum<E extends Enum<E>> { 
  ... 
}
The type Enum is the common base class of all enumeration types.  In Java an enumeration type such as Color is translated into a class Color that extends Enum<Color> . The purpose of the superclass Enum is to provide functionality that is common to all enumeration types. 

Here is a sketch of class Enum : 

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) { ... } 
}

The surprising feature in the declaration  " Enum<E extends Enum<E>> " is the fact that the newly defined class Enum and its newly defined type parameter E appear in the bound of that same type parameter.  It means that the Enum type must be instantiated for one of its subtypes.  In order to understand why this makes sense, consider that every enum type is translated into a subtype of Enum . 

Here is the contrived enum type Color : 

enum  Color {RED, BLUE, GREEN}
The compiler translates it into the following class: 
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 }); 
  } 
}

The inheritance has the effect that the Color type inherits all the methods implemented in Enum<Color> .  Among them is the compareTo method.  The Color.compareTo method should probably take a Color as an argument.  In order to make this happen class Enum is generic and the Enum.compareTo method takes Enum 's type parameter E as an argument.  As a result, type Color derived from Enum<Color> inherits a compareTo method that takes a Color as and argument, exactly as it should.  
 

If we dissect the declaration " Enum<E extends Enum<E>> " we can see that this pattern has several aspects. 

First, there is the fact that the type parameter bound is the type itself: " Enum <E extends Enum <E>> ". It makes sure that only subtypes of type Enum are permitted as type arguments. (Theoretically, type Enum could be instantiated on itself, like in Enum<Enum> , but this is certainly not intended and it is hard to imagine a situation in which such an instantiation would be useful.)

Second, there is the fact that the type parameter bound is the parameterized type Enum <E> ,  which uses the type parameter E as the type argument of the bound. This declaration makes sure that the inheritance relationship between a subtype and an instantiation of Enum is of the form " X extends Enum<X> ". A subtype such as " X extends Enum<Y> " cannot be declared because the type argument Y would not be within bounds; only subtypes of Enum<X> are within bounds.

Third, there is the fact that Enum is generic in the first place.  It means that some of the methods of class Enum take an argument or return a value of an unknown type (or otherwise depend on an unknown type). As we already know, this unknown type will later be a subtype X of Enum<X> .  Hence, in the parameterized type Enum<X> , these methods involve the subtype X , and they are inherited into the subtype X .  The compareTo method is an example of such a method; it is inherited from the superclass into each subclass and has a subclass specific signature in each case. 

To sum it up, the declaration " Enum<E extends Enum<E>> " can be decyphered as: Enum is a generic type that can only be instantiated for its subtypes, and those subtypes will inherit some useful methods, some of which take subtype specific arguments (or otherwise depend on the subtype).  

参考链接 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值