美文网首页
Java基础巩固-枚举的使用

Java基础巩固-枚举的使用

作者: Garwer | 来源:发表于2018-05-29 22:24 被阅读0次

    枚举:jdk1.5引入的新特性,允许用常量表示特定的数据片段,且全一类型安全的形式来表示。

    常用的定义常量方式

    public static final xxx ...例如:

    public static final int SEASON_SPRING = 1;
    public static final int SEASON_SUMMER = 2;
    public static final int SEASON_FALL = 3;
    public static final int SEASON_WINTER = 4;
    

    使用常量的缺点

    1.类型不安全,若一个方法要求传入季节参数。

    public Object getSeasonXXX(int seasonType) {
        ...
        return xxx;
    }
    //如果这个时候要调用getSeasonXXX根据传入的天气获取天气的一些相关属性,用常量的话,形参就是int类型,这个时候getSeasonXXX(SEASON_WINTER)和getSeasonXXX(4)都能获取冬天的天气属性,那么getSeasonXXX(5)也能编译过去而不会警告,但这样就不安全了。
    

    2.没有命名空间。开发者要在命名的时候以SEASON_开头,另外一个开发者再看这段代码的时候,才知道这四个常量分别代表季节。

    3.如果定义int值相同的变量,容易造成混淆。

    使用枚举类

    这个时候尝试利用枚举来定义常量,写个最简单的例子,例如

    public enum SeasonEnum {
        SPRING,SUMMER,FALL,WINTER;
    }
    

    将该类的编译后的class文件 javap(对编译的文件进行反编译)一下,可以看到类型默认继承java.lang.Enum


    简单用法
    public class testEnum1 {
        enum EnumW {
            SPRING,SUMMER,FALL,WINTER;
        }
        public static void main(String[] args) {
            EnumW enumW = EnumW.SPRING;
            System.out.println(enumW); //输出SPRING 
             System.out.println(enumW); //输出SPRING
             if (enumW.equals(enumW.toString())) { //这边不会输出相同 因为enumW不是String类型 但是有equals、toString()方法
                System.out.println("相同");
            }
        }
    }
    
    枚举类也可以定义属性和方法,例如
    public class testEnum2 {
        enum EnumW {
            SPRING("春天"),SUMMER("夏天"),FALL("秋天"),WINTER("冬天");//枚举类的实例必须放在第一行,如果放在下面编译会报错
            private final String name;
            private EnumW(String name) {//枚举类的构造器只能是私有的 这边改为public编译会有警告(可以自定义多个参数然后再get获取多个属性)
                this.name = name;
            }
            public String getName() {
                return name;
            }
        }
        public static void main(String[] args) {
            EnumW enumW = EnumW.SPRING;
            System.out.println(enumW.getName());//春天
        }
    }
    

    从上述例子可以看出枚举类的几个特点

    1. enum和class、interface的地位一样

    2. 使用enum定义的枚举类默认继承了java.lang.Enum,而不是继承Object类。枚举类可以实现一个或多个接口。

    3. 枚举类的所有实例都必须放在第一行展示,不需使用new 关键字,不需显式调用构造器。自动添加public static final修饰。

    4. 使用enum定义、非抽象的枚举类默认使用final修饰,不可以被继承,又因为继承了Enum类不能再继承其它类。

    5. 枚举类的构造器只能是私有的。

    枚举类的常用用法

    1.可以在switch case语句中直接使用枚举值,不需加入枚举类作为限定,使代码更加优雅
    public class testEnum3 {
        enum EnumW {
            SPRING,SUMMER,FALL,WINTER;
        }
         public void judge(EnumW s)
            {
                switch(s)
                {
                case SPRING: //直接使用枚举值做限定
                    System.out.println("春天适合踏青。");
                    break;
                case SUMMER:
                    System.out.println("夏天要去游泳啦。");
                    break;
                case FALL:
                    System.out.println("秋天一定要去旅游哦。");
                    break;
                case WINTER:
                    System.out.println("冬天要是下雪就好啦。");
                    break;
                }
            }
            
            public static void main(String[] args) {
                EnumW enumw = EnumW.SPRING; 
                testEnum testEnum = new testEnum();
                testEnum.judge(enumw);//春天适合踏青。
            }
    }
    

    思考

    1.枚举类是否可以定义抽象方法

    首先有抽象方法的类必然是抽象类,但是根据上面的反编译的类由final修饰而不是抽象类,但是枚举类又可以定义抽象方法,这是为什么呢。

    首先编写这么一段代码

    public enum AbstractTest {
        Spring {
            @Override
            public AbstractTest getSeason() {
                return Spring;
            }
        },
        Summer {
            @Override
            public AbstractTest getSeason() {
                return Summer;
            }
        },
        FALL {
            @Override
            public AbstractTest getSeason() {
                return FALL;
            }
        },
        WINTER {
            @Override
            public AbstractTest getSeason() {
                return WINTER;
            }
        };
        public abstract AbstractTest getSeason();
    
        public static void main(String[] args) {
            System.out.println(AbstractTest.Spring.toString());//Spring
        }
    }
    
    查看编译后的文件

    javac AbstractTest.java
    将java文件编译为class文件,会生成4个从1开始包含$+数字的class文件(匿名内部类)和一个主类(枚举类),这四个类继承了主类从而通过子类来实现抽象方法


    所以枚举类是可以带有抽象方法的,含有抽象方法的枚举类将自动修饰abstract并通过内部类来实现。

    相关文章

      网友评论

          本文标题:Java基础巩固-枚举的使用

          本文链接:https://www.haomeiwen.com/subject/rcqwjftx.html