java中枚举类型的使用

枚举类型是javaSE5中新加入的一个元素,它的功能比C++中枚举类型的功能完备的多,下面是一个简单的例子:
public enum  Dana {
    A,B,C,D
}
在这里创建了一个名为Dana的枚举类型,它有四个具名值,由于枚举类型的实例是常量,因此按照命名惯例它们都用大写字母表示(有多个单词则用下划线连接)
创建了一个枚举类型,那么怎么使用它呢,如下:
	public static void main(String[] args) {
		Dana dana = Dana.A;
		System.out.println(dana);
	}
}
这样就可以打印出枚举类型的值了,在创建enum时,编译器会自动添加一些有用的特性,比如,它会创建toString()方法,以便 你可以很方便地显示某个enum实例的名字,上面打印出来的效果也是这个原理,编译器还会创建ordinal()方法,用来表示某个特定enum常量的声明顺序,已经static values()方法,用来在按照enum常量的声明顺序,产生由这些常量值构成的数组:
public class EnumOrder {
 public static void main(String[] args) {
  for (Dana dana : Dana.values()) {
   System.out.println(dana + ",ordinal " + dana.ordinal());
  }
 }
}
打印效果:
 
尽管enum看起来像是一种新的数据类型,但是这个关键字只是为enum生成对应的类时产生了某些编译器行为,因此在很大程度上可以将enum当作其他任何类来处理,事实上,enum确实是类,并且有自己的方法。可以创建一个enum类,把它看做一个普通的类。除了它不能继承其他类了。(java是单继承,它已经继承了Enum),可以添加其他方法,覆盖它本身的方法 
下面我们看看怎么向enum中添加新方法:
public enum Dana {
	A("My name yi A"),
	B("My name yi B"),
	C("My name yi C"),
	D("My name yi D");
	private String description;
	private Dana (String description){
		this.description=description;
	}
	public String getDescription(){
		return description;
	}
	public static void main(String[] args) {
		for(Dana en : Dana.values()){
			System.out.println(en+": "+en.getDescription());
		}
	}
}

打印效果为:
 
注意,如果你打算定义自己的方法,那么必须在enum实例序列的最后添加一个分号,同时,java要求你必须先定义enum实例,如果在定义enum实例之前定义了任何方法或属性,那么在编译时就会得到错误信息。
在这个例子中,我们的构造器是私有的,但对于它的可访问性而言并没有什么变化,因为即使我们不声明为私有的,我们也只能在enum定义的内部使用其构造器创建enum实例,一旦enum的定义结束,编译器就不允许我们再使用其构造器来创建任何实例了。
再看一个覆盖enum的方法的例子:

public enum Color {
	RED("红色", 1), GREEN("绿色", 2), BLANK("白色", 3), YELLO("黄色", 4);
	// 成员变量
	private String name;
	private int index;
	// 构造方法
	private Color(String name, int index) {
		this.name = name;
		this.index = index;
	}
	//覆盖方法
	@Override
	public String toString() {
		return this.index+"_"+this.name;
	}
	public static void main(String[] args) {
		for(Color c : values()){
			System.out.println(c);
		}
	}
}

效果如下:
 


另外,enum有一个特别实用的特性,就是它可以在switch语句中使用:
下面是一个例子:
enum Signal {GREEN,YELLOW,RED }
public class TrafficLight {

	Signal color= Signal.RED;
	public void change(){
		switch(color){
		case RED : color = Signal.GREEN;
		break;
		case GREEN : color = Signal.YELLOW;
		break;
		case YELLOW : color =Signal.RED;
		break;
		}
	}
	public String toString() {
		return "The traffic light is " + color;
	}
	public static void main(String[] args) {
		TrafficLight t =new TrafficLight();
		for(int i=0;i<7;i++){
			System.out.println(t);
			t.change();
		}
	}
}

打印效果为:
 
由于switch是要在有限的可能值集合中进行选择,因此它与enum正是绝配,请注意enum的名字是如何能够倍加清楚地表明程序意欲何为的。

下面我们说一下把静态导入用于enum,先看一个例子:

package com.enumDemo;
import  static com.enumDemo.Enum.*;
public class Test {
	
	Enum degree;
	public Test(Enum degree){
		this.degree=degree;
	}
	public String toString(){
		return "Test is  "+degree;
	}
    public static void main(String[] args) {
		System.out.println(new Test(A));
		System.out.println(new Test(B));
		System.out.println(new Test(C));
	}
	
}

运行效果为:

 
使用statica import能够将enum实例的标识符带入当前的命名空间,所以无需再使用enum类型来修饰enum实例。这是一个好办法吗?还是显示地修饰enum实例更好呢?这要看代码得复杂程度了,编译器可以确保你使用的是正确的类型,唯一需要担心的是,使用静态导入会不会使你的代码看起来令人难以理解。在多数情况下,使用静态导入还是有好处的,不过这要具体情况具体分析了。
这里要特别注意,在定义enum的同一个文件中,这种技巧无法使用,如果是在默认包中定义enum,这种技巧也无法使用。(在Sun的内部对这一点也是持有不同意见,这里先不去讨论)
其实在创建enum时,编译器会为你生成一个相关的类,这个类时继承自java.lang.Enum,这里面有个有意思的问题,enum里面有个values()方法,但这个方法却不属于Enum,这是怎么回事呢,原理,values()是由编译器添加的static方法,可以看出,在创建enum的时候编译器还为其添加了valueOf()方法。由于values()方法是由编译器插入到enum定义中的static方法,所以,如果你将enum实例向上转型为Enum,那么values()方法就不可访问了,不过在Class中有一个getEnumConstants()方法,所以即便Enum接口中没有values()方法,我们仍然可以通过Class对象取得所有enum实例:如:
enum Search {
	HITHER, YOU
}

public class UpcastEnum {
	public static void main(String[] args) {
//		Search[] vals = Search.values();
		Enum e = Search.HITHER;
		for (Enum en : e.getClass().getEnumConstants())
			System.out.println(en);

	}
}
效果如下:
 
getEnumConstants()是Class上的方法,所以你甚至可以对不是每句的类调用此方法:
只不过,此时方法会返回null,所以当你试图使用其返回的结果时会发生异常。如下:

public class NonEnum {
	public static void main(String[] args) {
		Class<Integer> intClass = Integer.class;
		try {
			for (Object en : intClass.getEnumConstants())
				System.out.println(en);
		} catch (Exception e) {
			System.out.println(e);
		}
	}
}
运行效果如下:
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值