版权声明:本文为转载自Sup_Heaven的博客,原文链接为:http://blog.csdn.net/sup_heaven/article/details/35295851。
枚举类型概念
- 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枚举类型的案例一
- 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枚举类型的案例二
- 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枚举类型的案例三
案例三在二的基础上增加了构造时的参数个数,使得这样的枚举有更广泛的用处。
- 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;
- }
- }
- 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的实例而已。但后然发现不是这样的,先看看下面的一种枚举类型使用的代码。
- 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();
- }
别急,看了我对这个类的测试代码你就明白,测试代码如下:
- 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());
就是调用了匿名子类实现的方法。当然这些过程的很多事都有编译器等为我们做了,所以这里的代码很简单。
要是你不明白上面打印的内容,我再提供一个普通的类给你看看,还是类似的效果哦。
- 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普通类模拟枚举
- 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中提供的枚举特性
- /**
- * 枚举的应用
- * 存储每周中的天份
- */
- 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;
- }
- }
- }
枚举功能测试
- /**
- * 枚举功能测试
- */
- 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);
- }
- }
- }