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

清疚 2022-07-16 05:38 284阅读 0赞

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

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

public enum OzWitch {

  1. // enum实例必须定义在最前,并在方法之前:
  2. *WEST*("west."), *NORTH*("north."),
  3. *EAST*("east."), *SOUTH*("south.");//如果还有其他方法,则这个分号一定要写上
  4. **private** String description;//可以定义属性
  5. // 注,枚举的构造函数只能是包访问或private访问权限:
  6. **private** OzWitch(String description) \{
  7. **this**.description = description;
  8. \}
  9. //也可以有方法
  10. **public** String getDescription() \{
  11. **return** description;
  12. \}
  13. //还可以有main方法
  14. **public static void** main(String\[\] args) \{
  15. **for** (OzWitch witch : OzWitch.*values*())
  16. System.*out*.println(witch + ": " + witch.getDescription());
  17. \}

}

values()的神秘之处<<<

public enum Explore {

  1. *HERE*, *THERE*

}

使用javap反编译后:

public final class Explore extends java.lang.Enum{

  1. **public static final **Explore HERE;
  2. **public static final **Explore THERE;
  3. **public static final** Explore\[\] values();// 编译器自动添加的方法
  4. **public static **Explore valueOf(java.lang.String);// 编译器自动添加的方法
  5. **static** \{\};

}

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

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

enum Search { HITHER, YON }

public class UpcastEnum {

public static void main(String[] args) {

  1. Search\[\] vals = Search.*values*();
  2. Enum e = Search.*HITHER*; // 向上转型
  3. // e.values(); // Enum中没有 values()方法
  4. // 但我们可以通过Class对象的getEnumConstants()反射出enum实例
  5. **for**(Enum en : e.getClass().getEnumConstants())
  6. System.*out*.println(en);

}

}

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

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

enum CartoonCharacter implements Generator {

SLAPPY, SPANKY, BOB;

private Random rand = new Random(47);

public CartoonCharacter next() {

  1. **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) {

  1. **for**(LikeClasses en:*values*())\{
  2. en.behavior();//好比多态
  3. \}

}

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

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

}

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

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

发表评论

表情:
评论列表 (有 0 条评论,284人围观)

还没有评论,来说两句吧...

相关阅读

    相关 java编程思想:内部类

    可以将一个类的定义放在另一个类的定义的内部,这就是内部类。 起初看内部类只是一种名字隐藏和组织代码的模式。当生成内部类对象时,此对象与制造它的外围对象之间有一种联系,它可以访