枚举小结

最近项目中又用到了枚举类型,结果还是摆脱不了google查资料的境地,用一次查一次,也慢慢失去了对自己记忆力的自信,看来还是稍微记一下的好。

 

一、什么是枚举

      枚举是 java5中新加的一种类型,但是我们并不陌生,因为在其它语言中早已存在。说白了就是预先定义一组常量,并作为一个新的类型,而这种新类型的取值范围是确定了的,只能在这组常量里面。

 

      什么时候使用枚举呢?一个最重要的依据是取值范围,一个用枚举表示的对象,在你的项目或系统里 的取值范围应该是确定的,不变的。最著名的例子莫过天用于表示星期几。

 

二、如何定义

       很简单,在大括号里罗列它的值就可以了。

一个表示星期几的枚举类:

Java代码 复制代码  收藏代码
  1. public enum Week {   
  2.     SUNDAY,   
  3.     MONDAY,   
  4.     TUESDAY,   
  5.     WEDNESDAY,   
  6.     THURSDAY,   
  7.     FRIDAY,   
  8.     SATURDAY;   
  9. }  
public enum Week {
	SUNDAY,
	MONDAY,
	TUESDAY,
	WEDNESDAY,
	THURSDAY,
	FRIDAY,
	SATURDAY;
}

 

三、用枚举的好处

我认为首先它表义,和现实逻辑更接近。从编程上来说,它使我们程序更简单了。

 

在java中,枚举出现以前,我们大多数是用静态变量来实现类似功能的。如:

Java代码 复制代码  收藏代码
  1. public class StaticWeek {   
  2.     public static final int SUNDAY = 0;   
  3.     public static final int MONDAY = 1;   
  4.     public static final int TUESDAY = 2;   
  5.     public static final int WEDNESDAY = 3;   
  6.     public static final int THURSDAY = 4;   
  7.     public static final int FRIDAY = 5;   
  8.     public static final int SATURDAY = 6;   
  9. }  
public class StaticWeek {
	public static final int SUNDAY = 0;
	public static final int MONDAY = 1;
	public static final int TUESDAY = 2;
	public static final int WEDNESDAY = 3;
	public static final int THURSDAY = 4;
	public static final int FRIDAY = 5;
	public static final int SATURDAY = 6;
}

在上面的描述中,我们用StaticWeek.MONDAY 来表示星期一,但这是一种假象,是我们程序人员对自己的一种自我催眠。对于java虚拟机而言它还是int型,和int  1 没区别。

 

比如有一个类它有一个私有变量dayOfWeek表示星期几:

Java代码 复制代码  收藏代码
  1. private int dayOfWeek = StaticWeek.SUNDAY;   
  2. private Week dayOfWeek2 = Week.SUNDAY;   
  3.   
  4. public void setDayOfWeek(int dayOfWeek) {   
  5.     this.dayOfWeek = dayOfWeek;   
  6. }  
private int dayOfWeek = StaticWeek.SUNDAY;
private Week dayOfWeek2 = Week.SUNDAY;

public void setDayOfWeek(int dayOfWeek) {
	this.dayOfWeek = dayOfWeek;
}
  • 这个变量有一个初始值StaticWeek.SUNDAY,但是它和int 0 没区别,只是我们为了程序好理解,人为作的一种规则,当然这种规则也给我们带来了很大的方便。
  • 它还有一个set方法,但它的参数类型是int型,所以它参数值并未局限于我们定义的七种静态量。所以你给它一个8,它也不会拒绝,但这显然也是不合我们定义的逻辑的,所以我们还要验证参数值是否合法。这里很不方便,如果传入的参数一定是合法的该有多好啊,如果接收的参数只能是我定义的七种值就妙不可言了!
Java代码 复制代码  收藏代码
  1. myObj.setDayOfWeek(StaticWeek.FRIDAY);//我们都人为希望大家都这样写,但这需要人的自觉   
  2. myObj.setDayOfWeek(1);//功能同上   
  3. myObj.setDayOfWeek(8);//并未杜绝这种情况的调用,实际上是不合法  
myObj.setDayOfWeek(StaticWeek.FRIDAY);//我们都人为希望大家都这样写,但这需要人的自觉
myObj.setDayOfWeek(1);//功能同上
myObj.setDayOfWeek(8);//并未杜绝这种情况的调用,实际上是不合法
 

用枚举来实现上面类似的功能:

Java代码 复制代码  收藏代码
  1. private Week dayOfWeek2 = Week.SUNDAY;   
  2.   
  3. public void setDayOfWeek2(Week dayOfWeek2) {   
  4.     this.dayOfWeek2 = dayOfWeek2;   
  5. }  
private Week dayOfWeek2 = Week.SUNDAY;

public void setDayOfWeek2(Week dayOfWeek2) {
	this.dayOfWeek2 = dayOfWeek2;
}

 

Java代码 复制代码  收藏代码
  1. myObj.setDayOfWeek2(Week.FRIDAY);   
  2.            
  3. //下面的调用是不合法,编译期就会报错,枚举限制了调用类型,只能是Week类型,这也确定了它的取值范围,而且保证是合法的   
  4. myObj.setDayOfWeek2(otherType);  
myObj.setDayOfWeek2(Week.FRIDAY);
		
//下面的调用是不合法,编译期就会报错,枚举限制了调用类型,只能是Week类型,这也确定了它的取值范围,而且保证是合法的
myObj.setDayOfWeek2(otherType);
  •   首先我们看到我们定义的私有变量就是Week类型的,它是一种类型,而这种类型的取值范围是我们自己定义的 ,所以它怎么取值都不会跑出我们的手掌心,如果万一超出了,你可以去找Sun先生问一下,但首先一定要先确认不是自己的错。
  • 再看方法,我们把参数类类型设置成了Week类型,这样就再也不会有人写出那种让人不理解的代码了(myObj.setDayOfWeek(8)) ,因为有Sun先生为你把关。

 

三、枚举使用举例

一般的使用可以参考上面,唯一值的注意的如何取得一个该类型的实例:类型前缀.要取的值

 

API:values() ,取得一个包括所有值的该枚举类型数组,如遍历一个枚举

Java代码 复制代码  收藏代码
  1. for(Week w:Week.values()){   
  2.     System.out.println(w);   
  3. }  
for(Week w:Week.values()){
	System.out.println(w);
}

 输出结果:

Java代码 复制代码  收藏代码
  1. SUNDAY   
  2. MONDAY   
  3. TUESDAY   
  4. WEDNESDAY   
  5. THURSDAY   
  6. FRIDAY   
  7. SATURDAY  
SUNDAY
MONDAY
TUESDAY
WEDNESDAY
THURSDAY
FRIDAY
SATURDAY

 

API:valueOf() ,取出一个枚举的一值

Java代码 复制代码  收藏代码
  1. System.out.println(Week.valueOf("MONDAY"));//同Week.MONDAY  
System.out.println(Week.valueOf("MONDAY"));//同Week.MONDAY

 

API.Enum.valueOf(class,String) ,一个静态方法,取出某个枚举类型的某个值。

Java代码 复制代码  收藏代码
  1. System.out.println(Enum.valueOf(Week.class"MONDAY"));//同上  
System.out.println(Enum.valueOf(Week.class, "MONDAY"));//同上
 

基本上枚举就定义了上面三个方法,当然我们还可以编写自己的方法和自己的构造函数。

 

 

在switch中使用枚举

我们为那个有dayOfWeek2变量的类定义一个打印信息的方法

Java代码 复制代码  收藏代码
  1. public void printInfo(){   
  2.         String day;   
  3.            
  4.         switch(this.dayOfWeek2){   
  5.             case SUNDAY:   
  6.                 day = "星期天";   
  7.                 break;   
  8.             case MONDAY:   
  9.                 day = "星期一";   
  10.                 break;   
  11.             case TUESDAY:   
  12.                 day = "星期二";   
  13.                 break;   
  14.             case WEDNESDAY:   
  15.                 day = "星期三";   
  16.                 break;   
  17.             case THURSDAY:   
  18.                 day = "星期四";   
  19.                 break;   
  20.             case FRIDAY:   
  21.                 day = "星期五";   
  22.                 break;   
  23.             case SATURDAY:   
  24.                 day = "星期六";   
  25.                 break;   
  26.             default:   
  27.                 day = "星期几?";   
  28.         }   
  29.            
  30.         System.out.println("我是"+day);   
  31.     }  
public void printInfo(){
		String day;
		
		switch(this.dayOfWeek2){
			case SUNDAY:
				day = "星期天";
				break;
			case MONDAY:
				day = "星期一";
				break;
			case TUESDAY:
				day = "星期二";
				break;
			case WEDNESDAY:
				day = "星期三";
				break;
			case THURSDAY:
				day = "星期四";
				break;
			case FRIDAY:
				day = "星期五";
				break;
			case SATURDAY:
				day = "星期六";
				break;
			default:
				day = "星期几?";
		}
		
		System.out.println("我是"+day);
	}
  •  注意,枚举在case字句中的情况,是不包括枚举类型的前缀的。

我们使用一下上面的方法:

Java代码 复制代码  收藏代码
  1. myObj.setDayOfWeek2(Week.FRIDAY);   
  2. myObj.printInfo();  
myObj.setDayOfWeek2(Week.FRIDAY);
myObj.printInfo();

 输出结果:

Java代码 复制代码  收藏代码
  1. 我是星期五  
我是星期五

 

自定义构造函数和自己的方法

改造Week:

Java代码 复制代码  收藏代码
  1. public enum Week {   
  2.     SUNDAY("日"),   
  3.     MONDAY("一"),   
  4.     TUESDAY("二"),   
  5.     WEDNESDAY("三"),   
  6.     THURSDAY("四"),   
  7.     FRIDAY("五"),   
  8.     SATURDAY("六");   
  9.        
  10.     private String name;   
  11.        
  12.     Week(String name){   
  13.         this.name = "星期"+name;   
  14.     }   
  15.        
  16.     public String toString(){   
  17.         return this.name;   
  18.     }   
  19. }  
public enum Week {
	SUNDAY("日"),
	MONDAY("一"),
	TUESDAY("二"),
	WEDNESDAY("三"),
	THURSDAY("四"),
	FRIDAY("五"),
	SATURDAY("六");
	
	private String name;
	
	Week(String name){
		this.name = "星期"+name;
	}
	
	public String toString(){
		return this.name;
	}
}

 如上,枚举类型可以自定义自己的构造函数,自己的私有变量,自己的方法,重写方法。

 

根据改造的类我们可以重写上面打印信息方法printInfo():

Java代码 复制代码  收藏代码
  1. public void printInfo2(){   
  2.     System.out.println("我是"+this.dayOfWeek2.toString());   
  3. }  
public void printInfo2(){
	System.out.println("我是"+this.dayOfWeek2.toString());
}
 

枚举的构造函数

  • 构造函数前面是不能有修饰符的,或者你只能写private,即不允许我们人为调用的
  • 当定义一个枚举类型时,实际上已经确定了它的实例对象,如Week, 只有七个实例对象
  • 实例对象的构造,也是我们预先定义好的,如Week.MONDAY对象,它的构造:MONDAY("一“),而括号里的字符串就是我们传到构造函数的参数。
  • 何时构造,枚举类型的所有实例是一起构造的,当我们初次使用某个实例时。如:当我们第一次使用任何一个Week实例时,都会构造七个实例。

      

更改构造函数,增加一个输出

Java代码 复制代码  收藏代码
  1. Week(String name){   
  2.         System.out.println(name);//在初次使用时,所有值的构造会调一往遍   
  3.         this.name = "星期"+name;   
  4.     }  
Week(String name){
		System.out.println(name);//在初次使用时,所有值的构造会调一往遍
		this.name = "星期"+name;
	}

 当我们第一次使用Week的实例时:

Java代码 复制代码  收藏代码
  1. System.out.println("3");   
  2. myObj.setDayOfWeek2(Week.FRIDAY);   
  3. System.out.println("4");  
System.out.println("3");
myObj.setDayOfWeek2(Week.FRIDAY);
System.out.println("4");

 输出结果

Java代码 复制代码  收藏代码
  1. 3  
  2. 日   
  3. 一   
  4. 二   
  5. 三   
  6. 四   
  7. 五   
  8. 六   
  9. 4  
3
日
一
二
三
四
五
六
4

 

 

三、总结完毕

本文链接: http://kino.iteye.com/blog/204949 转载请注明出处,谢谢。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值