您的位置:首页 > 编程语言 > Java开发

Java枚举类型

2016-03-09 16:16 519 查看
版权声明:本文为转载自Sup_Heaven的博客,原文链接为:http://blog.csdn.net/sup_heaven/article/details/35295851。

枚举类型概念

[java] view
plain copy







package com.lxq.enumm;

public class EnumDemoOne

{

private enum InnerEnum

{

RED, GREEN, YELLOW

};

public static void main(String[] args)

{

System.out.println(InnerEnum.RED);

System.out.println(InnerEnum.GREEN);

System.out.println(InnerEnum.YELLOW);

}

}

运行上面的代码,将编辑产生EnumDemoOne.class和EnumDemoOne$InnerEnum.class。

由此说明定义枚举类型其实就是在定义一个类,只不过很多细节由编译器帮你补齐了,所以,某种程度上enum关键词的作用就像是class或interface.当使用enum定义枚举类型时,实际上所定义出来的类型是继承自java.lang.Enum类。

Java枚举类型的案例一

[java] view
plain copy







package com.lxq.enumm;

public class EnumDemoTwo

{

public enum ColorSelect

{

red, green, yellow, blue;

}

public static void main(String[] args)

{

/*

* 枚举类型是一种类型,用于定义变量,以限制变量的赋值 赋值时通过"枚举名.值"来取得相关枚举中的值

*/

ColorSelect m = ColorSelect.blue;

switch (m)

{

/*注意:枚举重写了ToString(),说以枚举变量的值是不带前缀的

* 所以为blue而非ColorSelect.blue

*/

case red:

System.out.println("color is red");

break;

case green:

System.out.println("color is green");

break;

case yellow:

System.out.println("color is yellow");

break;

case blue:

System.out.println("color is blue");

break;

}

System.out.println("遍历ColorSelect中的值");

/*通过values()获得枚举值的数组*/

for (ColorSelect c : ColorSelect.values())

{

System.out.println(c);

}

System.out.println("枚举ColorSelect中的值有:"+ColorSelect.values().length+"个");

/*ordinal()返回枚举值在枚举中的索引位置,从0开始*/

System.out.println(ColorSelect.red.ordinal());//0

System.out.println(ColorSelect.green.ordinal());//1

/*name()返回枚举值在枚举中的索引位置,从0开始*/

System.out.println(ColorSelect.yellow.name());//yellow

System.out.println(ColorSelect.blue.name());//blue

/*枚举默认实现了java.lang.Comparable接口,-1之前,0位置相同,1之后*/

System.out.println(ColorSelect.red.compareTo(ColorSelect.green));

/*静态valueOf()方法可以让您将指定的字符串尝试转换为枚举类型*/

ColorSelect red=ColorSelect.valueOf("red");

System.out.println(red.getClass());

}

}

Java枚举类型的案例二

上面案例一的枚举类型的返回值仅仅是该枚举变量的名称而已,我们当然也可以通过参数自己制定更加友好更加形象的枚举类型的返回值。

[java] view
plain copy







package com.lxq.enumm;

import java.util.EnumMap;

import java.util.EnumSet;

public class EnumDemoThree{

// 1. 定义枚举类型

public enum Light {

/*利用构造函数传参利用构造函数传参

* 通过括号赋值,而且必须有带参构造器和属性和方法,否则编译出错

* 赋值必须是都赋值或都不赋值,不能一部分赋值一部分不赋值

* 如果不赋值则不能写构造器,赋值编译也出错

* */

RED ("红色"), GREEN ("绿色"), YELLOW ("黄色");

// 定义私有变量

private String clor ;

// 构造函数,枚举类型只能为私有

private Light(String clor) {

this.clor = clor;

}

public String getClor(){

return this.clor;

}

public void setClor(String clor){

this.clor=clor;

}

@Override

public String toString() {

return this.clor;

}

}

/**

* @param args

*/

public static void main(String[] args ) {

// 1. 遍历枚举类型

System.out.println( " 演示枚举类型的遍历 ......" );

testTraversalEnum ();

// 2. 演示 EnumMap 对象的使用

System. out .println( " 演示 EnmuMap 对象的使用和遍历 ....." );

testEnumMap ();

// 3. 演示 EnmuSet 的使用

System. out .println( " 演示 EnmuSet 对象的使用和遍历 ....." );

testEnumSet ();

}

/**

* 演示枚举类型的遍历

*/

private static void testTraversalEnum() {

Light[] allLight = Light.values ();

for (Light aLight : allLight) {

System. out .println( " 当前灯 name : " + aLight.name());

System. out .println( " 当前灯 ordinal : " + aLight.ordinal());

System. out .println( " 当前灯: " + aLight);

}

}

/**

* 演示 EnumMap 的使用, EnumMap 跟 HashMap 的使用差不多,只不过 key 要是枚举类型

*/

private static void testEnumMap() {

// 1. 演示定义 EnumMap 对象, EnumMap 对象的构造函数需要参数传入 , 默认是 key 的类的类型

EnumMap<Light, String> currEnumMap = new EnumMap<Light, String>(

Light. class );

currEnumMap.put(Light. RED , " 红灯 " );

currEnumMap.put(Light. GREEN , " 绿灯 " );

currEnumMap.put(Light. YELLOW , " 黄灯 " );

// 2. 遍历对象

for (Light aLight : Light.values ()) {

System. out .println( "[key=" + aLight.name() + ",value="

+ currEnumMap.get(aLight) + "]" );

}

}

/**

* 演示 EnumSet 如何使用, EnumSet 是一个抽象类,获取一个类型的枚举类型内容 <BR/>

* 可以使用 allOf 方法

*/

private static void testEnumSet() {

EnumSet<Light> currEnumSet = EnumSet.allOf (Light. class );

for (Light aLightSetElement : currEnumSet) {

System. out .println( " 当前 EnumSet 中数据为: " + aLightSetElement);

}

}

}

Java枚举类型的案例三

案例三在二的基础上增加了构造时的参数个数,使得这样的枚举有更广泛的用处。

[java] view
plain copy







package com.lxq.enumm;

public enum EnumConstant

{

WEEK_00("", "请选择"),WEEK_01("01", "周一"), WEEK_02("02", "周二"), WEEK_03("03", "周三");

private String key;

private String value;

//自定义的构造函数,参数数量,名字随便自己取

//构造器默认也只能是private, 从而保证构造函数只能在内部使用

private EnumConstant(String key, String value)

{

this.key = key;

this.value = value;

}

public String getKey()

{

return key;

}

public void setKey(String key)

{

this.key = key;

}

public String getValue()

{

return value;

}

public void setValue(String value)

{

this.value = value;

}

//重新toString方法,默认的toString方法返回的就是枚举变量的名字,和name()方法返回值一样

@Override

public String toString()

{

return this.key+":"+this.value;

}

}

[java] view
plain copy







package com.lxq.enumm;

public class EnumTest

{

/**

* @param args

*/

public static void main(String[] args)

{

EnumConstant[] allday = EnumConstant.values();

System.out.println("-----------for begin------------------");

for (EnumConstant day : allday)

{

System.out.println(" name : " + day.name());//枚举变量的名称

System.out.println(" ordinal : " + day.ordinal());//枚举变量的序号

System.out.println(" : " + day);//就是toString()的返回值

System.out.println(" key : " + day.getKey());//取得第一个参数

System.out.println(" value : " + day.getValue());//取得第二个参数

}

System.out.println("-----------for end------------------");

System.out.println(EnumConstant.WEEK_00);//就是toString()的返回值

System.out.println(EnumConstant.WEEK_01);//就是toString()的返回值

System.out.println(EnumConstant.WEEK_02);//就是toString()的返回值

System.out.println(EnumConstant.WEEK_03);//就是toString()的返回值

}

}

本以为RED只是一个Color类的一个static final的实例而已。但后然发现不是这样的,先看看下面的一种枚举类型使用的代码。

[java] view
plain copy







package com.lxq.enumm;

public enum Color

{

RED{

public String getName(){

return "红色";

}

}

,GREEN{

public String getName(){

return "绿色";

}

}

,YELLOW{

public String getName(){

return "黄色";

}

};

public abstract String getName();

}

如果RED只是一个Color类的一个static final的实例,那么上面的代码就很让了费解了,为什么在枚举类型中可以有一个抽象方法,而每个枚举值可以对其重新实现?

别急,看了我对这个类的测试代码你就明白,测试代码如下:

[java] view
plain copy







import java.lang.reflect.Modifier;

public class EnumDemoFour{

public static void main(String[] args){

//打印该枚举值的名称

System.out.println(Color.RED.getName());

//打印该枚举值的类

System.out.println(Color.RED.getClass());

//打印该枚举值的类的父类

System.out.println(Color.RED.getClass().getSuperclass());

//打印该枚举值的类的父类的父类

System.out.println(Color.RED.getClass().getSuperclass().getSuperclass());

//打印该枚举类型的修饰符

System.out.println(Modifier.toString(Color.class.getModifiers()));

}

/*运行结果

红色

class com.lxq.enumm.Color$1

class com.lxq.enumm.Color

class java.lang.Enum

public abstract*/

}

该运行结果首先说明了RED和Color不是同一个类,而是前者是后者的一个子类;同时也说明了enum申明的其实是一个abstract的类,所以Color中可以有抽象方法。

那么,我们应该这么理解枚举类型的原理,首先enum Color继承了java.lang.Enum这个抽象类,但enum Color还是一个抽象类,所以它可以有抽象方法和非抽象方法。

而enum Color中的枚举值变量RED事实上上Color的一个匿名子类,所以它可以实现Color中的抽象方法,这样,当我们调用System.out.println(Color.RED.getName());

就是调用了匿名子类实现的方法。当然这些过程的很多事都有编译器等为我们做了,所以这里的代码很简单。

要是你不明白上面打印的内容,我再提供一个普通的类给你看看,还是类似的效果哦。

[java] view
plain copy







public abstract class TestInnerClass

{

public abstract void dosomething();

public static void main(String[] args){

TestInnerClass tic=new TestInnerClass(){

@Override

public void dosomething()

{

System.out.println("我是匿名子类");

}

};

tic.dosomething();

System.out.println(tic.getClass());

}

/*输出结果

我是匿名子类

class TestInnerClass$1

*/

}

最后再附上网上一个使用Java普通类模拟枚举的例子http://blog.csdn.net/xyang81/article/details/7185428,这个例子真的很好。

使用Java普通类模拟枚举

[java] view
plain copy







import java.util.HashMap;

import java.util.Map;

/**

* 模拟星期中的表示的天,每个星期天都表示一个对象

* 1、类中的每一个枚举成员都是该类的一个实例对象

* 2、构造函数私有化

* 3、提供操作枚举成员的抽象方法和静态方法

*/

public abstract class WeekDate {

/**

* 星期一

*/

public static final WeekDate MON = new WeekDate("MON",0) {//匿名子类

@Override

public WeekDate nextDay() {

return TUES;

}

@Override

public WeekDate preDay() {

return SUN;

}

@Override

public String toString() {

return "WeekDate.MON";

}

};

/**

* 星期二

*/

public static final WeekDate TUES = new WeekDate("TUES",1) {

@Override

public WeekDate nextDay() {

return WEDNES;

}

@Override

public WeekDate preDay() {

return MON;

}

@Override

public String toString() {

return "WeekDate.TUES";

}

};

/**

* 星期三

*/

public static final WeekDate WEDNES = new WeekDate("WEDNES",2) {

@Override

public WeekDate nextDay() {

return THURS;

}

@Override

public WeekDate preDay() {

return TUES;

}

@Override

public String toString() {

return "WeekDate.WEDNES";

}

};

/**

* 星期四

*/

public static final WeekDate THURS = new WeekDate("THURS",3) {

@Override

public WeekDate nextDay() {

return FRI;

}

@Override

public WeekDate preDay() {

return WEDNES;

}

@Override

public String toString() {

return "WeekDate.THURS";

}

};

/**

* 星期五

*/

public static final WeekDate FRI = new WeekDate("FRI",4){

@Override

public WeekDate nextDay() {

return SATUR;

}

@Override

public WeekDate preDay() {

return THURS;

}

@Override

public String toString() {

return "WeekDate.FRI";

}

};

/**

* 星期六

*/

public static final WeekDate SATUR = new WeekDate("SATUR",5){

@Override

public WeekDate nextDay() {

return SUN;

}

@Override

public WeekDate preDay() {

return FRI;

}

@Override

public String toString() {

return "WeekDate.SATUR";

}

};

/**

* 星期日

*/

public static final WeekDate SUN = new WeekDate("SUN",6){

@Override

public WeekDate nextDay() {

return MON;

}

@Override

public WeekDate preDay() {

return SATUR;

}

@Override

public String toString() {

return "WeekDate.SUN";

}

};

private static Map<String, WeekDate> valueMap = new HashMap<String, WeekDate>();

/**

* 枚举名称

*/

private final String name;

/**

* 枚举成员的顺序

*/

private final int ordinal;

private WeekDate(String name,int ordinal) {

this.name = name;

this.ordinal = ordinal;

}

/**

* 保存枚举成员

*/

private static WeekDate[] values = {

MON,TUES,WEDNES,THURS,FRI,SATUR,SUN

};

//初始化

static {

valueMap.put("MON", values[0]);

valueMap.put("TUES", values[1]);

valueMap.put("WEDNES", values[2]);

valueMap.put("THURS", values[3]);

valueMap.put("FRI", values[4]);

valueMap.put("SATUR", values[5]);

valueMap.put("SUN", values[6]);

}

/**

* 下一天

* @return

*/

public abstract WeekDate nextDay();

/**

* 前一天

* @return

*/

public abstract WeekDate preDay();

/**

* 枚举中的所有成员

* @return

*/

public static WeekDate[] values() {

return values;

}

/**

* 将一个字符串转换成一个枚举成员对象

* @param name 枚举名称

* @return 枚举对象

*/

public static WeekDate valueOf(String name) {

if (name.equalsIgnoreCase("MON")) {

return MON;

} else if (name.equalsIgnoreCase("TUES")) {

return TUES;

} else if (name.equalsIgnoreCase("WEDES")) {

return WEDNES;

} else if (name.equalsIgnoreCase("THURS")) {

return THURS;

} else if (name.equalsIgnoreCase("FRI")) {

return FRI;

} else if (name.equalsIgnoreCase("SATUR")) {

return SATUR;

} else if (name.equalsIgnoreCase("SUN")) {

return SUN;

} else {

throw new IllegalArgumentException("找不到" + name + "枚举类型!");

}

}

/**

* 优化字符串转枚举对象

* @param name 枚举名称

* @return 枚举对象

*/

public static WeekDate valueOf_2(String name) {

WeekDate value = valueMap.get(name.toUpperCase());

if (value == null) {

throw new IllegalArgumentException("找不到" + name + "枚举类型!");

}

return value;

}

public String getName() {

return name;

}

public int getOrdinal() {

return ordinal;

}

}

使用JDK5.0中提供的枚举特性

[java] view
plain copy







/**

* 枚举的应用

* 存储每周中的天份

*/

public enum WeekDateEnum {

MON {

@Override

public WeekDateEnum nextDay() {

return TUES;

}

@Override

public WeekDateEnum preDay() {

return SUN;

}

}, TUES {

@Override

public WeekDateEnum nextDay() {

return WEDNES;

}

@Override

public WeekDateEnum preDay() {

return MON;

}

}, WEDNES {

@Override

public WeekDateEnum nextDay() {

return THURS;

}

@Override

public WeekDateEnum preDay() {

return TUES;

}

}, THURS {

@Override

public WeekDateEnum nextDay() {

return FRI;

}

@Override

public WeekDateEnum preDay() {

return WEDNES;

}

}, FRI {

@Override

public WeekDateEnum nextDay() {

return SATUR;

}

@Override

public WeekDateEnum preDay() {

return THURS;

}

}, SATUR {

@Override

public WeekDateEnum nextDay() {

return SATUR;

}

@Override

public WeekDateEnum preDay() {

return FRI;

}

}, SUN {

@Override

public WeekDateEnum nextDay() {

return SATUR;

}

@Override

public WeekDateEnum preDay() {

return MON;

}

};

private WeekDateEnum() {}

/**

* 下一天

* @return

*/

public abstract WeekDateEnum nextDay();

/**

* 前一天

* @return

*/

public abstract WeekDateEnum preDay();

/**

* 枚举对象公共的toString方法,可以在case块中反馈自己想要返回的信息

*/

public String toString() {

switch (this) {

case MON:

return "WeekDateEnum.MON";

case TUES:

return "WeekDateEnum.TUES";

case WEDNES:

return "WeekDateEnum.WEDNES";

case THURS:

return "WeekDateEnum.THURS";

case FRI:

return "WeekDateEnum.FRI";

case SATUR:

return "WeekDateEnum.SATUR";

case SUN:

return "WeekDateEnum.SUN";

default:

return null;

}

}

}

枚举功能测试

[java] view
plain copy







/**

* 枚举功能测试

*/

public class EnumTest {

public static void main(String[] args) {

//使用普通JAVA类模拟枚举的应用

WeekDate weekDate = WeekDate.MON; //获得一个枚举对象

//调用枚举中提供的方法

System.out.println(weekDate.nextDay());

System.out.println(weekDate.preDay());

System.out.println(weekDate.getName());

//获得枚举成员所在枚举成员列表中的位置

System.out.println(weekDate.getOrdinal());

//调用某一个枚举成员的方法

System.out.println(WeekDate.values()[0].preDay());

System.out.println("---------------遍历枚举成员,普通JAVA类模拟--------------------------");

for (WeekDate weekDate2 : WeekDate.values()) {

System.out.println(weekDate2);

}

System.out.println("\n=================================================================\n");

//使用JDK中提供的枚举特性功能应用

WeekDateEnum weekDateEnum = WeekDateEnum.MON; //获得一个枚举对象

System.out.println(WeekDate.values().length); //获得枚举成员数量

System.out.println(weekDateEnum.name()); //获得枚举的字符串名称

System.out.println(weekDateEnum.toString()); //打印枚举对象,已重写toString方法,默认打印枚举的名称

System.out.println(weekDateEnum.nextDay().ordinal()); //枚举成员列表中的位置

System.out.println(WeekDateEnum.valueOf("FRI").nextDay().ordinal());

System.out.println("---------------遍历枚举成员,使用JDK的枚举特性-------------------------");

for (WeekDateEnum enumDemo : WeekDateEnum.values()) {

System.out.println(enumDemo);

}

}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: