枚举超详细介绍

文章目录

什么是枚举类

类的对象只有有限个,确定的

例如:星期、季节、支付方式、
订单状态:Nonpayment(未付款)、 Paid(已付款) 、Delivered (已发货)、 Return (退货)、Checked (已确认 )、Fulfilled (已配货)
就职状态、
线程状态:

BLOCKED 一个线程的线程状态阻塞等待监视器锁定
NEW 线程尚未启动的线程状态
RUNNABLE 可运行线程的线程状态
TERMINATED 终止线程的线程状态
TIMED_WAITING 具有指定等待时间的等待线程的线程状态
WAITING 等待线程的线程状态

什么时候使用枚举类

需要定义一组常量时,如果枚举类中只有一个对象,则可以作为单例模式的实现方式

为什么要用枚举类

1)出于类型安全考虑,没用枚举类之前,常用静态常量来表示
对于性别的表示,
public static final int MAN = 0;
public static final int WOMAN = 1;
其一,这些变量完全可用来做加减运算,当然我们原意并非如此
其二,意义不明,当我们debug的时候,本来想输出‘男’,结果输出0

2)代码更优雅
一个大一些的程序里面,可能要用到成百上千的静态常量,如果全写在一个文件里面,容易造成命名混淆,程序读起来也比较麻烦

3)枚举类能方便我们定义自己想要的类型
枚举便于记忆和使用,并且相当于一个接口。使用时只需要封装内部的数据类型,并且限定数据域。而且对于不同的枚举变量,可以调用不同的处理方法

自定义枚举类

class Season{
    // 1.声明Season对象的属性
    private String seasonName;
    private String seasonDesc;
    // 2.私有化构造器
    private Season(String seasonName, String seasonDesc){
        this.seasonName = seasonName;
        this.seasonDesc = seasonDesc;
    }
    // 3.提供枚举类的对象
    public static final Season SPRING = new Season("春天","春暖花开");
    public static final Season SUMMER = new Season("夏天","夏日炎炎");
    public static final Season AUTUMN = new Season("秋天","秋高气爽");
    public static final Season WINTER = new Season("冬天","冰天雪地");
    public String getSeasonName() {
        return seasonName;
    }
    public String getSeasonDesc() {
        return seasonDesc;
    }
    @Override
    public String toString() {
        return "Season{" +
                "seasonName='" + seasonName + '\'' +
                ", seasonDesc='" + seasonDesc + '\'' +
                '}';
    }
}
public class test {
    public static void main(String[] args) {
        Season spring = Season.SPRING;
        System.out.println(spring);
    }
}

enum定义枚举类

Season1是默认继承java.lang.Enum ,则不能继承其他类了,而且默认是final类

实现接口

enum Season1 implements info { 
    // 实现接口方式二 让枚举类的对象分别实现接口中的抽象方法
    SPRING("春天", "春暖花开"){ // ordinal() 0
        @Override
        public void show() {
            System.out.println("这是春天");
        }
    }, // 相当于 匿名内部类
    SUMMER("夏天", "夏日炎炎"){ // 1
        @Override
        public void show() {
            System.out.println("这是夏天");
        }
    },
    AUTUMN("秋天", "秋高气爽"){// 2
        @Override
        public void show() {
            System.out.println("这是秋天");
        }
    },
    WINTER("冬天", "冰天雪地"){// 3
        @Override
        public void show() {
            System.out.println("这是冬天");
        }
    },
    WUCAN { // 4
        @Override
        public void show() {
            System.out.println("无参");
        }
    };
    private String seasonName;
    private String seasonDesc;
    private Season1() {

    }
    private Season1(String seasonName, String seasonDesc) {
        this.seasonName = seasonName;
        this.seasonDesc = seasonDesc;
    }
    public String getSeasonName() {
        return seasonName;
    }
    public String getSeasonDesc() {
        return seasonDesc;
    }
    // 实现接口 方式一
  /*  @Override
    public void show() {
			 System.out.println("相同的行为");
    }*/
}
interface info {
    void show();
}
public class test2 {
    public static void main(String[] args) {
        Season1 autumn = Season1.AUTUMN;
        System.out.println(autumn);// toString()
        System.out.println(Season1.class.getSuperclass());
        Season1[] values = Season1.values();
        for (int i = 0; i < values.length; i++) {
            System.out.println(values[i]);
            values[i].show();
        }

        Season1 winter = Season1.valueOf("WINTER");
        System.out.println(winter);// WINTER

        Thread.State[] values1 = Thread.State.values();
        for (int i = 0; i < values1.length; i++) {
            System.out.println(values1[i]);
        }
    }
}

没有实现接口

// 如果枚举类 没有实现接口,结果和自定义枚举类是一样的
enum Season1 { 
    SPRING("春天", "春暖花开"),// 相当于 public static final Season SPRING = new Season("春天","春暖花开");
    SUMMER("夏天", "夏日炎炎"),
    AUTUMN("秋天", "秋高气爽"),
    WINTER("冬天", "冰天雪地"),
    WUCAN ;

    private String seasonName;
    private String seasonDesc;
    private Season1() {
    }
   private Season1(String seasonName, String seasonDesc) {
        this.seasonName = seasonName;
        this.seasonDesc = seasonDesc;
    }
    public String getSeasonName() {
        return seasonName;
    }
    public String getSeasonDesc() {
        return seasonDesc;
    }
}

public class test2 {
    public static void main(String[] args) {
        Season1 autumn = Season1.AUTUMN;
        System.out.println(autumn.name());
        System.out.println(autumn);
        // 输出枚举对象的次序,从0开始
        System.out.println(autumn.ordinal());// 2
        Season1 s = Season1.SPRING;
        System.out.println(s.compareTo(autumn));// -2
        System.out.println(s.getDeclaringClass());// class test.Season1
        System.out.println(s.getClass());// class test.Season1
        System.out.println(autumn.getClass());// class test.Season1
    }
}

Enum类的主要方法

toString() 返回枚举对象常量的名称

  /**
     * 用switch重写toString方法,提高代码健壮性
     * @return
     */
    @Override
    public String toString() {
        //switch支持Enum类型
        switch (this) {
            case MONDAY:
                return "今天星期一";
            case TUESDAY:
            case WEDNESDAY:
                return "今天星期三";
            case THURSDAY:
                return "今天星期四";
            case FRIDAY:
                return "今天星期五";
            case SATURDAY:
                return "今天星期六";
            case SUNDAY:
                return "今天星期日";
            default:
                return "Unknow Day";
        }
    }

values() 返回枚举类型的对象数组 // javap Season1.class 可以看到

valueOf(String str) 可以把一个字符串转为对应的枚举类对象

name 枚举常量的名称,建议优先使用toString

ordinal 得到当前枚举常量的次序

compareTo return self.ordinal() - other.ordinal()

getDeclaringClass 得到枚举常量所属枚举类型的Class对象,用它来判断两个枚举常量是否属于同一个枚举类型

// 以上 实现接口的枚举 
public class test2 {
    public static void main(String[] args) {
        Season1 autumn = Season1.AUTUMN;
        System.out.println(autumn.name());
        System.out.println(autumn);
        // 输出枚举对象的次序,从0开始
        System.out.println(autumn.ordinal());// 2
        Season1 s = Season1.SPRING;
        System.out.println(s.compareTo(autumn));// -2
        System.out.println(s.getDeclaringClass());// class test.Season1
        System.out.println(s.getClass());// class test.Season1$1
        System.out.println(autumn.getClass());// class test.Season1$3
    }
}

clone 枚举类型不能被clone,为了防止子类实现克隆方法,Enum实现了仅抛出 CloneNotSupportedException异常的不变Clone()

switch使用枚举类型

switch 使用枚举类型对象,case 使用 枚举常量

public static void main(String[] args) {
    InputStreamReader isr = new InputStreamReader(System.in);
    BufferedReader br = new BufferedReader(isr);
    try {
        System.out.println("请输入1-7");
        int i = Integer.parseInt(br.readLine());
        switch (i) {
            case 1 :
                System.out.println(Week.MONDAY);
                printWeek(Week.MONDAY);
                break;
            case 2 :
                System.out.println(Week.TUESDAY);
                printWeek(Week.TUESDAY);
                break;
            case 3 :
                System.out.println(Week.WEDNESDAY);
                printWeek(Week.WEDNESDAY);
                break;
            case 4 :
                System.out.println(Week.THURSDAY);
                printWeek(Week.THURSDAY);
                break;
            case 5 :
                System.out.println(Week.FRIDAY);
                printWeek(Week.FRIDAY);
                break;
            case 6 :
                System.out.println(Week.SATURDAY);
                printWeek(Week.SATURDAY);
                break;
            case 7 :
                System.out.println(Week.SUNDAY);
                printWeek(Week.SUNDAY);
                break;
        }
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        if (br != null) {
            try {
                br.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}
public static void printWeek(Week week) {
    switch (week) {
        case MONDAY :
            System.out.println(Week.MONDAY.getWeekName());
            break;
        case TUESDAY:
            System.out.println(Week.TUESDAY.getWeekName());
            break;
        case WEDNESDAY:
            System.out.println(Week.WEDNESDAY.getWeekName());
            break;
        case THURSDAY:
            System.out.println(Week.THURSDAY.getWeekName());
            break;
        case FRIDAY:
            System.out.println(Week.FRIDAY.getWeekName());
            break;
        case SATURDAY:
            System.out.println(Week.SATURDAY.getWeekName());
            break;
        case SUNDAY:
            System.out.println(Week.SUNDAY.getWeekName());
            break;
    }
}
enum Week {
    MONDAY("星期一"),
    TUESDAY("星期二"),
    WEDNESDAY("星期三"),
    THURSDAY("星期四"),
    FRIDAY("星期五"),
    SATURDAY("星期六"),
    SUNDAY("星期日");
    private final String weekName;
    Week(String weekName) {
        this.weekName = weekName;
    }
    public String getWeekName() {
        return weekName;
    }
}

使用==比较枚举类型

equals(),枚举类型中可以直接使用== 来比较,Enum中的equals也是直接使用==来实现的,它的存在是在Set List Map中使用,equals是不可变的

其中 == 运算符用于比较状态,并且如果两个值均为null 都不会引发 NullPointerException。相反,如果使用equals方法,将抛出 NullPointerException:

Pizza.PizzaStatus pizza = null;
System.out.println(pizza.equals(Pizza.PizzaStatus.DELIVERED));//空指针异常
System.out.println(pizza == Pizza.PizzaStatus.DELIVERED);//正常运行
Week status = Week.MONDAY;
Week status2 = Week.TUESDAY;
Week status3 = Week.MONDAY;
System.out.println(status==status3);// true
System.out.println(status.equals(status3));// true
System.out.println(status==status2);// false
System.out.println(status.equals(status2));// false

持续更新。。。

EnumSet

EnumMap

枚举实现设计模式

单例

策略模式

Java 8 与枚举

Enum 类型的 JSON 表现形式

上一篇:[2020BUAA软工助教]助教每周小结(week 10)


下一篇:Coursera课程笔记----C程序设计进阶----Week 4