标签:
枚举(enum)是一个被命名的整型常量的集合。
enum相对于普通常量最明显的好处在于更有组织性。
尽管enum看起来像是一种新的数据类型,事实上,enum是一种受限制的类,并且具有自己的方法。
创建enum时,编译器会为你生成一个相关的类,这个类继承自java.lang.Enum。
java.lang.Enum类声明:
public abstract class Enum<E extends Enum<E>> implements Comparable<E>,
Serializable {} |
在enum中,提供了一些基本方法:
values()返回enum实例的数组,而且该数组中的元素严格保持在enum中声明时的顺序。
name()返回实例名。
ordinal()返回实例声明时的次序,从0开始。
getDeclaringClass()返回实例所属的enum类型。
可以使用==来比较enum实例,编译器会自动提供equals()和hashCode()方法。此外,java.lang.Enum实现了Comparable和Serializable接口,所以也提供compareTo()方法。
例:展示enum的基本特性
注:有个小细节,如果枚举中没有定义方法,可以在最后一个实例后面加逗号或分号或什么符号都不加
enum Color { RED, GREEN, BLUE // 如果枚举中没有定义方法,也可以在最后一个实例后面加逗号或分号 // RED, GREEN, BLUE, // RED, GREEN, BLUE; }; public class EnumDemo { public static void main(String args[]) { for (Color c : Color.values()) { System.out.println(c + " ordinal: " + c.ordinal()); System.out.print(c.compareTo(Color.GREEN) + " "); System.out.print(c.equals(Color.GREEN) + " "); System.out.println(c == Color.GREEN); System.out.println(c.getDeclaringClass()); System.out.println(c.name()); System.out.println("==================================="); } } }; |
输出:
RED
ordinal: 0 -1 false
false class
com.notes.enumeration.Color RED =================================== GREEN
ordinal: 1 0 true
true class
com.notes.enumeration.Color GREEN =================================== BLUE
ordinal: 2 1 false false class
com.notes.enumeration.Color BLUE =================================== |
C、C++语言中的enum,可以为实例直接赋值,但是Java不能用“=”为enum实例赋值。
例:C、C++语言中的enum初始化
#include "stdafx.h" #include <iostream> using namespace std; typedef enum{ ONE = 1, TWO, THREE = 3, TEN = 10 } Number; int _tmain(int argc, _TCHAR* argv[]) { cout << Number::ONE << endl; cout << Number::TWO << endl; cout << Number::THREE << endl; cout << Number::TEN << endl; return 0; } |
输出:
1 2 3 10 |
Java虽然不能直接为实例赋值,但是它有更优秀的解决方案:为enum添加方法。
除了不能继承自一个enum外,基本上可以将enum看做一个常规的类(因为enum都继承自类,且Java不支持多重继承,所以enum不能再继承其他类)。
创建新的enum时,可以为其添加多种方法,甚至可以为其添加构造方法。
注意一个细节:如果要为enum定义方法,那么必须在enum的最后一个实例尾部添加一个分号。此外,在enum中,必须先定义实例,不能将字段或方法定义在实例前面。否则,编译器会报错。
例:列举一个错误码的枚举,全面展示如何在枚举中定义普通方法、静态方法、抽象方法、构造方法
public enum ErrorCode { OK(0) { public String getName() { return "成功"; } }, ERROR_A(100) { public String getName() { return "错误A"; } }, ERROR_B(200) { public String getName() { return "错误B"; } }; private ErrorCode(int number) { // 构造方法 this.number = number; } private int number; public int getNumber() { // 普通方法 return number; } public abstract String getName(); // 抽象方法 public static String getAll() { // 静态方法 String result = "["; for(ErrorCode code : ErrorCode.values()){ result += code.getName() + ", "; } result += "]"; return result; } public static void main(String args[]) { System.out.println("getAll: " + ErrorCode.getAll()); for (ErrorCode s : ErrorCode.values())
{ System.out.println("name: " + s.getName() + ", number: " + s.getNumber()); } } } |
在上例中,刻意将构造方法声明为private,但对于它的可访问性而言,没有什么变化。因为我们只能在enum的内部使用构造器来创建enum实例。一旦enum结束定义,编译器就不允许我们再使用构造器来创建任何实例了。事实上,enum的构造器只能被声明为private权限或不声明权限。
输出:
getAll: [成功, 错误A, 错误B, ] name: 成功, number: 0 name: 错误A, number: 100 name: 错误B, number: 200 |
创建新的enum时,允许覆写java.lang.Enum中的方法
例:覆写toString()方法
enum Signal { RED, GREEN, YELLOW; public String toString() { return "覆写toString()方法"; } public static void main(String args[]) { System.out.println("toString: " + Signal.RED.toString()); } }; |
输出:
toString: 覆写toString()方法 |
创建新的enum时,可以实现一个或多个接口。
实现了接口的enum类型,也可以像普通类一样做向上转型为它所实现的接口。这样的好处在于,有利于组织代码。
例:Fruit和Animal都实现了Print接口,可以像普通类一样做向上转型为Print。
interface Print { public String getName(); } enum Fruit implements Print { Apple { public String getName() { return "苹果"; } }, Orange { public String getName() { return "橘子"; } }, PEAR { public String getName() { return "梨子"; } }; } enum Animal implements Print { Dog { public String getName() { return "狗"; } }, Cat { public String getName() { return "猫"; } }, Bird { public String getName() { return "鸟"; } }; } public class InterfaceEnumDemo { public static void main(String args[]) { // Fruit和Animal都实现了Print接口,可以像普通类一样做向上转型为Print for (Print p : Fruit.values()) { System.out.print(p.getName() + " "); } System.out.println(); for (Print p : Animal.values()) { System.out.print(p.getName() + " "); } } }; |
enum和switch的关系就像是方糖之于咖啡。
swtich中只能使用整型值,而枚举实例天生就具备整数值的次序,所以二者常常被组合使用来实现状态机。
例:
enum Signal { RED, GREEN, YELLOW }; public class TrafficLight { public static String getState(Signal signal) { String state = null; switch (signal) { case RED: state = "红灯停"; break; case GREEN: state = "绿灯行"; break; case YELLOW: state = "黄灯要小心"; break; default: state = "异常"; break; } return state; } public static void main(String args[]) { System.out.println("state: " + TrafficLight.getState(Signal.GREEN)); } } |
输出:
state: 绿灯行 |
标签:
原文地址:http://www.cnblogs.com/jingmoxukong/p/5203561.html