《java编程思想》第十九章 枚举

enum的values()方法返回enum实例的数组,而且该数组中的元素严格保持其在enum中声声明时的顺序。

 

创建enum时,编译器会为你生成一个相关的类,这个类继承自java.lang.Enum。

 

Enum类实例的ordinal()方法返回一个int值,这是每个enum实例在声明时的次序,从0开始。可以使用==来比较enum实例,编译器会自动为你提供equals()和hashCode()方法。

 

Enum类实现了Comparable接口,所以它具有compareTo()方法,同时,它还实现了Serializable接口。

 

name()方法返回enum实例声明的名字,与使用toString()方法效果一样。

 

valueOf(Class<T> enumType, String name)是在Enum中定义的static方法,它根据所给定的名字返回相应的enum实例,如果不存在给定名字的实例,将会抛出异常。

扫描二维码关注公众号,回复: 4084196 查看本文章

 

除了不能继承自一个enum之外,我们基本上可以将enum看作一个常规的类,也就是说,我们可以向enum中添加方法属性。

 

public enum OzWitch {

       // enum实例必须定义在最前,并在方法之前:

       WEST("west."), NORTH("north."),

       EAST("east."), SOUTH("south.");//如果还有其他方法,则这个分号一定要写上

      

       private String description;//可以定义属性

 

       // 注,枚举的构造函数只能是包访问或private访问权限:

       private OzWitch(String description) {

              this.description = description;

       }

 

       //也可以有方法

       public String getDescription() {

              return description;

       }

 

       //还可以有main方法

       public static void main(String[] args) {

              for (OzWitch witch : OzWitch.values())

                     System.out.println(witch + ": " + witch.getDescription());

       }

}

 

>>>values()的神秘之处<<<

public enum Explore {

       HERETHERE

}

使用javap反编译后:

public final class Explore extends java.lang.Enum{

    public static final Explore HERE;

    public static final Explore THERE;

    public static final Explore[] values();// 编译器自动添加的方法

    public static Explore valueOf(java.lang.String);// 编译器自动添加的方法

    static {};

}

Enum类没有values()方法,values()是由编译器为enum添加的static方法,在创建Explore的过程中,编译器还为它创建了valueOf(String name)方法,这可能有点怪了,Enum类不是已经有valueOf(Class<T> enumType, String name)了吗?不过Enum中的valueOf()方法需要两个参数,而这个新增的方法只需一个参数。

由于values()方法是由编译器插入到enum定义中的static方法,所以,如果你将enum实例向上转型为Enum,那么values()方法就不可访问了。不过,在Class中有一个getEnumConstants()方法,所以即使Enum接口中没有values()方法,我们仍然可以通过Class对象取得所有enum实例(注:只有是Enum类型的Class才能调用getEnumConstants方法,否则抛空指针异常):

enum Search { HITHERYON }

public class UpcastEnum {

  public static void main(String[] args) {

    Search[] vals = Search.values();

    Enum e = Search.HITHER; // 向上转型

    // e.values(); // Enum中没有 values()方法

    // 但我们可以通过Class对象的getEnumConstants()反射出enum实例

    for(Enum en : e.getClass().getEnumConstants())

      System.out.println(en);

  }

}

 

>>>enum还可实现其它接口<<<

由于enum可以看是一个普通的类,所以他还可以实现其他接口。

enum CartoonCharacter implements Generator<CartoonCharacter> {

  SLAPPYSPANKYBOB;

  private Random rand = new Random(47);

  public CartoonCharacter next() {

    return values()[rand.nextInt(values().length)];

  }

}

 

 

>>>枚举实例的“多态”表现<<<

enum LikeClasses {

  WINKEN { void behavior() { System.out.println("Behavior1"); } },

  BLINKEN { void behavior() { System.out.println("Behavior2"); } },

  NOD { void behavior() { System.out.println("Behavior3"); } };

  abstract void behavior();//抽象方法,由每个enum实例实现,当然也可是一个实体方法

  public static void main(String[] args) {

       for(LikeClasses en:values()){

              en.behavior();//好比多态

       }

  }

// 但不能把枚举实例看作是类,因为它们只是一个实例

  // void f1(LikeClasses.WINKEN instance) {}

}

经过反编译后,我们发现生成了四个类LikeClasses.class、LikeClasses$2.class、

LikeClasses$3.class、LikeClasses$1.class,而且LikeClasses$xx.class继承自LikeClasses.class类,并将各自的behavior方法代码放入到自己相应的类文件中。

猜你喜欢

转载自blog.csdn.net/fromatozhappy/article/details/52751883
今日推荐