Java基础巩固-枚举的使用

枚举: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


Java基础巩固-枚举的使用_第1张图片
简单用法
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
    }
}
Java基础巩固-枚举的使用_第2张图片
查看编译后的文件

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


Java基础巩固-枚举的使用_第3张图片
所以枚举类是可以带有抽象方法的,含有抽象方法的枚举类将自动修饰abstract并通过内部类来实现。

你可能感兴趣的:(Java基础巩固-枚举的使用)