Java枚举总结
声明:本文仅仅是总结学习笔记,使用了以下3篇文章
1. java枚举
(http://cardyn.iteye.com/blog/904534)
2. 详细介绍java中的枚举类型
(http://developer.51cto.com/art/201107/275031.htm)
3. Java 枚举7常见种用法
(http://www.iteye.com/topic/1116193)
一. Thinking in Java 定义:
关键字ENUM 可以将一组具名的值的有限集合创建为一种新的类型,而这些具名的值可以作为常规的程序组件使用。
二. 使用枚举的意义:
枚举就是要让某个类型的变量的取值只能为若干个固定值中的一个,否则,编译器就会报错。枚举可以让编译器在编译时就可以控制源程序中填写的非法值,普通变量的方式在开发阶段无法实现这一目标。
三. 没有枚举类型的时候
采用A. 私有构造函数B. 每个元素用公有的静态成员变量表示并且调用私有构造函数,来模拟枚举类型
/**
* 颜色类
*/
classColor{
/**
* 每个元素用公有的静态成员变量表示
*/
//红色
public static finalColor RED =newColor();
//蓝色
public static finalColor BLUE =newColor();
//黑色
public static finalColor BLACK =newColor();
/**
* 私有的构造函数
* 防止外部创建该对象
*/
privateColor(){}
}
四.枚举类型的详细介绍
/**
* 颜色枚举
*/
enumColor {
RED, BLUE,BLACK, YELLOW,GREEN;
}
显然,enum很像特殊的class,实际上enum声明定义的类型就是一个类。而这些类都是类库中Enum类的子类(java.lang.Enum)。它们继承了这个Enum中的许多有用的方法。我们对代码编译之后发现,编译器将enum类型单独编译成了一个字节码文件:Color.class。
final enumhr.test.Color {
// 所有的枚举值都是类静态常量
public static final enumhr.test.Color RED;
public static final enumhr.test.Color BLUE;
public static final enumhr.test.Color BLACK;
public static final enumhr.test.Color YELLOW;
public static final enum hr.test.ColorGREEN;
private static finalsynthetic hr.test.Color[] ENUM$VALUES;
// 初始化过程,对枚举类的所有枚举值对象进行第一次初始化
static{
0 newhr.test.Color [1]
3 dup
//把枚举值字符串“RED”压入操作数栈
4 ldc [16]
// 把整型值0压入操作数栈
6 iconst_0
//调用Color类的私有构造器创建Color对象RED
7 invokespecial hr.test.Color(java.lang.String, int) [17]
//将枚举对象赋给Color的静态常量RED。
10 putstatic hr.test.Color.RED : hr.test.Color [21]
//枚举对象BLUE等与上同
102 return
};
// 私有构造器,外部不可能动态创建一个枚举类对象(也就是不可能动态创建一个枚举值)。
privateColor(java.lang.String arg0,int arg1){
// 调用父类Enum的受保护构造器创建一个枚举对象
3 invokespecial java.lang.Enum(java.lang.String, int) [38]
};
public statichr.test.Color[] values();
// 实现Enum类的抽象方法
public statichr.test.Color valueOf(java.lang.String arg0);
}
下面我们就详细介绍enum定义的枚举类的特征及其用法。(后面均用Color举例)
A. Color枚举类就是class,而且是一个不可以被继承的final类
其枚举值(RED,BLUE.。.)都是Color类型的类静态常量, 我们可以通过下面的方式来得到Color枚举类的一个实例:
//获得一个枚举值
Colorc = Color.RED;
注意:这些枚举值都是public static final的,也就是我们经常所定义的常量方式,因此枚举类中的枚举值最好全部大写。
B. 即然枚举类是class,当然在枚举类型中有构造器,方法和数据域
但是,枚举类的构造器有很大的不同:
1. 构造器只是在构造枚举值的时候被调用
/**
* 颜色枚举
*/
enumColor {
RED(255,0, 0),
BLUE(0,0, 255),
BLACK(0,0, 0),
YELLOW(255,255, 0),
GREEN(0,255, 0);
// 构造枚举值,比如RED(255,0,0)
privateColor(int rv,int gv, int bv){
this.redValue =rv;
this.greenValue =gv;
this.blueValue =bv;
}
// 覆盖了父类Enum的toString()
publicString toString() {
return "(" + redValue + ","
+ greenValue + ","
+ blueValue + ")";
}
// 自定义数据域,private为了封装。
private int redValue;
private int greenValue;
private int blueValue;
}
2.构造器只能私有private,绝对不允许有public构造器。 这样可以保证外部代码无法新构造枚举类的实例。这也是完全符合情理的,因为我们知道枚举值是public static final的常量而已。 但枚举类的方法和数据域可以允许外部访问
public static voidmain(String[] args) {
//编译错误,外部不可以实例化Color
//Colorcolors=new Color(100,200,300);
//获得一个枚举值
Color c = Color.RED;
//调用了toString()方法 输出 (255,0,0)
System.out.println(c);
}
3.所有枚举类都继承了Enum的方法,下面我们详细介绍这些方法
l ordinal()
返回枚举值在枚举类种的顺序。这个顺序根据枚举值声明的顺序而定
Color.RED.ordinal(); //返回结果:0
Color.BLUE.ordinal();//返回结果:1
l compareTo()
Enum实现了java.lang.Comparable接口,因此可以比较象与指定对象的顺序。Enum中的compareTo返回的是两个枚举值的顺序之差。当然,前提是两个枚举值必须属于同一个枚举类,否则会抛出ClassCastException()异常。(具体可见源代码)
Color.RED.compareTo(Color.BLUE);//返回结果 -1
l values()
静态方法,返回一个包含全部枚举值的数组
//获得包含全部枚举值的数组
Color[] colors=Color.values();
//遍历输出
for(Color color : colors) {
System.out.print(color.name()+"" + color + "-");
}
//结果:RED(255,0,0)-BLUE(0,0,255)-BLACK(0,0,0)-YELLOW(255,255,0)-GREEN(0,255,0)
l toString()
返回枚举常量的名称
Color c = Color.RED;
System.out.println(c);//返回结果: RED
l valueOf()
这个方法和toString方法是相对应的,返回带指定名称的指定枚举类型的枚举常量
//返回结果: Color.BLUE
Colorblue = Color.valueOf("BLUE");
//(0,0,255)
System.out.println(blue);
l equals()
比较两个枚举类对象的引用
//JDK源代码:
public final booleanequals(Object other) {
return this==other;
}
五.Java 枚举7常见种用法
1.常量
在JDK1.5 之前,我们定义常量都是: public static fianl ....。现在好了,有了枚举,可以把相关的常量分组到一个枚举类型里,而且枚举提供了比常量更多的方法
/**
* 颜色枚举
*/
enum Color {
RED, BLUE,BLACK, YELLOW,GREEN;
}
2.switch
//获得红色枚举
Colorcolor = Color.RED;
//使用判断
switch(color) {
case RED:
System.out.println("it‘s red");
break;
case BLUE:
System.out.println("it’s blue");
break;
case BLACK:
System.out.println("it‘s blue");
break;
}
//结果:it‘s red
3.向枚举中添加新方法
如果打算自定义自己的方法,那么必须在enum实例序列的最后添加一个分号。而且 Java 要求必须先定义 enum 实例
enumColor {
RED("红色", 1),GREEN("绿色", 2),BLANK("白色", 3),YELLO("黄色", 4);
// 成员变量
privateStringname;
private int index;
// 构造方法
privateColor(String name,intindex) {
this.name =name;
this.index =index;
}
/**
* 用户自定义方法
* 获得颜色名称
*/
public staticString getName(intindex) {
for(Color c : Color.values()) {
if(c.getIndex() == index) {
return c.name;
}
}
return null;
}
// get set 方法
publicString getName() {
returnname;
}
public voidsetName(String name) {
this.name =name;
}
public intgetIndex() {
returnindex;
}
public voidsetIndex(intindex) {
this.index =index;
}
}
public static voidmain(String[] args) {
//获得红色枚举
Color color = Color.RED;
//红色
System.out.println(color.getName(color.getIndex()));
}
4.覆盖枚举的方法
上面示例已经有了
5. 实现接口
/**
* 行为接口
*/
interfaceBehaviour {
/**
* 输出
*/
voidprint();
/**
* 获得信息
*/
String getInfo();
}
enum Color implements Behaviour {
RED("红色", 1),GREEN("绿色", 2),BLANK("白色", 3),YELLO("黄色", 4);
// 成员变量
privateStringname;
private int index;
// 构造方法
privateColor(String name,intindex) {
this.name =name;
this.index =index;
}
/**
* 接口方法:输出
*/
@Override
public voidprint() {
System.out.println(this.index+":"+this.name);
}
/**
* 接口方法:获得信息
*/
@Override
publicString getInfo() {
return this.name;
}
// get set 方法
publicString getName() {
returnname;
}
public voidsetName(String name) {
this.name =name;
}
public intgetIndex() {
returnindex;
}
public voidsetIndex(intindex) {
this.index =index;
}
}
public static voidmain(String[] args) {
//获得红色枚举
Color color = Color.RED;
//1:红色
color.print();
//红色
System.out.println(color.getInfo());
}
6.使用接口组织枚举
/**
* 食物接口
*/
public interface Food{
/**
* 咖啡枚举
*/
enumCoffee implements Food{
BLACK_COFFEE, DECAF_COFFEE, LATTE,CAPPUCCINO
}
/**
* 甜点枚举
*/
enumDessertimplements Food{
FRUIT, CAKE,GELATO
}
}
7.关于枚举集合的使用
java.util.EnumSet和java.util.EnumMap是两个枚举集合。EnumSet保证集合中的元素不重复;EnumMap中的 key是enum类型,而value则可以是任意类型
//初始化EnumSet
EnumSet<Color>colorSet = EnumSet.allOf(Color.class);
//遍历输出
for(Color temp : colorSet) {
System.out.print(temp+"-");
}
//结果:RED-GREEN-BLANK-YELLO
//初始化EnumMap
EnumMap<Color,String> colorMap = newEnumMap<Color, String>(Color.class);
//赋值
colorMap.put(Color.RED,"我是红色");
colorMap.put(Color.BLANK,"我是蓝色");
//遍历输出
for(Color key : colorMap.keySet()) {
System.out.println(colorMap.get(key));
}
//结果:我是红色/我是蓝色