枚举

    xiaoxiao2025-12-23  10

                                                                                           

                            关于枚举-----jdk1.5的新特性之一

    一.为什么要有枚举

          在软件开发中关于定义变量星期天(int weekDay)的值时,刚开始我规定 int weekDay = 7;但是时间长了,对int weekDay = 7的规定会忘却,到下一次要定义变量int weekDay = ?时,我可能会定义成0,那会和以前定义的不一致而出问题。(在多人开发中也会出现这样的问题,有人会定义成0,也有人会定义成7),使用枚举就可以避免上述情况的发生。

    二.枚举的定义

         定义:是指将变量的值一一列出来,变量的值只限于列举出来的值的范围内.(比如星期,就只有星期一-星期天,用枚举合适),枚举是一种特殊的类,其中的每个元素都是该类的一个实例对象,例如可以调用WeekDay.SUN.getClass().getName()和WeekDay.class.getName。

                      枚举就是要让某个类型的变量的取值只能为若干个固定值中的一个,否则,编译器就会报错。枚举可以让编译器在编译时就可以控制源程序中填写的非法值,普通变量的方式在开发阶段无法实现这一目标。

    示例:我有一个枚举 WeekDay

    public enum WeekDay{         SUN,MON

    }

      FRI我在枚举里面没有定义,所以编译报错。

    三.枚举的好处

         防止程序出错,统一变量取值,避免在开发时对一些固定变量取值前后不一的情况。

    四.枚举的示例

           1.用普通类来模拟枚举的实现原理

    /**  * 用普通类实现枚举原理  * @author JSON  *  */ public class WeekDay {     /**      * 私有构造函数方法,为了防止WeekDay被随便的实例化      */     private WeekDay(){}          //定义静态常量星期一     public final static WeekDay MON = new WeekDay();     //定义静态常量星期二     public final static WeekDay TUE = new WeekDay();     //定义静态常量星期天     public final static WeekDay SUN = new WeekDay();     //下面省略了星期三,四,五,六

        //...

        /**      * 获得下一天      * @return      */     public WeekDay nextDay(){         if(this==MON){             return TUE;         }else if(this==TUE){             return SUN;         }else{             return MON;         }     }     //打印名字的方法     public String toString(){         //当只有2个元素的时候可以只有写,但是有三个元素就不能这样写了。         //return this == SUN?"SUN":"MON";//三元运算符         if(this==SUN){             return "SUN";         }else if(this==TUE){             return "TUE";         }else{             return "MON";         }     } }

    //main函数是程序入口,可以在类里面的任何地方,但是必须在一个类中

    //public static void main(String[] args) {}-----------1 //public class Student { //    public static void main(String[] args) {}---------2 //} //public static void main(String[] args) {}-----------3

    //1,3错的位置,2是对的位置

    public static void main(String[] args){         //星期一的对象         WeekDay mon = WeekDay.MON;         System.out.println(mon.toString());         System.out.println(mon.nextDay().toString());         System.out.println(mon.nextDay().nextDay().toString());

    }

    输出结果:

    MON TUE SUN

    上面是一个简单类实现枚举的代码,对于上面的if-else,写起来是不是很麻烦呢?如有还有许多个变量,那些if-else岂不是很麻烦,于是上面的代码还可以改进改进

    /**  * 用普通类实现枚举原理(用了抽象方法)  * @author JSON  *  */ public abstract class WeekDay {     /**      * 私有构造函数方法,为了防止WeekDay被随便的实例化      */     private WeekDay(){}          //定义静态常量星期一     public final static WeekDay MON = new WeekDay(){         @Override//这是注解(覆盖的意思)         public WeekDay nextDay() {             // TODO Auto-generated method stub             return TUE;         }         @Override//这是注解(覆盖的意思)         public String toString() {             // TODO Auto-generated method stub             return "MON";         }              };     //定义静态常量星期二     public final static WeekDay TUE = new WeekDay(){         @Override//这是注解(覆盖的意思)         public WeekDay nextDay() {             // TODO Auto-generated method stub             return SUN;         }         @Override//这是注解(覆盖的意思)         public String toString() {             // TODO Auto-generated method stub             return "TUE";         }              };     //定义静态常量星期天     public final static WeekDay SUN = new WeekDay(){         @Override//这是注解(覆盖的意思)         public WeekDay nextDay() {             // TODO Auto-generated method stub             return MON;         }         @Override//这是注解(覆盖的意思)         public String toString() {             // TODO Auto-generated method stub             return "SUN";         }              };     /**      * 获得下一天(抽象方法,类也要是抽象的类)      * @return      */     public abstract WeekDay nextDay();     /**      * 打印名字的方法(抽象方法,类也要是抽象的类)      */     public abstract String toString(); }

    public static void main(String[] args){         //星期一的对象         WeekDay mon = WeekDay.MON;         System.out.println(mon.toString());         System.out.println(mon.nextDay().toString());         System.out.println(mon.nextDay().nextDay().toString());

    }

    输出结果:

    MON TUE SUN

    输出的结果是一样的,但是第二种方法比第一种方法更加的好一些。

               2.用枚举类的关键字来实现枚举

    //定义一个枚举对象     public enum WeekDay{         SUN,MON,TUE,WED,THI,FRI,SAT     }     public static void main(String[] args){         //全大写的命名方式是常量的         WeekDay fri= WeekDay.FRI;         System.out.println(fri);         System.out.println(fri.name());//得到枚举对象的名字         System.out.println(fri.ordinal());//排在几位         System.out.println(fri.valueOf("SUN"));//返回带指定名称的指定枚举类型的枚举常量。(查看JDK帮助文档知道的)         System.out.println(fri.valueOf("WED").toString());         System.out.println(fri.values().length);         System.out.println(fri.valueOf("AAA"));//输入一个不存在的枚举变量,编译没错,运行报错       }

    输出结果:

    当你看到这时,并且打印出了上面的结果,那就表明你掌握了枚举的入门。接下来更进一步的了解枚举,外带一个思考题。

    //定义一个枚举对象     public enum WeekDay{         //public WeekDay(){};//这里会报错,原因为枚举的元素列表必须位于在所有的         //成分之前,如果枚举的元素列表后有东西,那元素列表后面得有分号';'         SUN(),MON(1),TUE,WED,THI,FRI,SAT; //        public WeekDay(){};//这里用public会报错,原因是:枚举构造函数,只有私人的非法修改是允许的。(鼠标移到小红X上,把显示出来的英语拿给google翻译)         private WeekDay(){System.out.println("first");};         private WeekDay(int day){System.out.println("second");};     }     public static void main(String[] args){               //全大写的命名方式是常量的         WeekDay weekDay2 = WeekDay.FRI;     }

    输出结果为:

    first second first first first first first

         思考:SUN()和MON(1)与TUE和SUN()他们有区别吗?为什么?还有输出结果第二行为什么是“second”?-------这里面涉及了方法的重载哈

    下面是枚举的最复杂的方式---------张孝祥老师说的

    public enum TrafficLamp{         //RED{}代表为TrafficLamp的子类         RED(30){             @Override             public TrafficLamp nextLamp() {                 // TODO Auto-generated method stub                 return GREEN;             }                      },         //GREEN{}代表为TrafficLamp的子类         GREEN(45){             @Override             public TrafficLamp nextLamp() {                 // TODO Auto-generated method stub                 return YELLWO;             }                      },         //YELLWO{}代表为TrafficLamp的子类         YELLWO(5){             @Override             public TrafficLamp nextLamp() {                 // TODO Auto-generated method stub                 return RED;             }                      };         public abstract TrafficLamp nextLamp();         private int time;         private TrafficLamp(int time){             this.time = time;         }     }

    最后有个小知识点就是:枚举只有一个成员时,就可以作为一种单例的实现方法。

    最新回复(0)