程序笔记   发布时间:2022-07-21  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了Java基础 - 枚举大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。

目录
  • 引言
  • 语法
    • 基础语法
    • 定义方法
    • 常用方法
      • name()
      • ordinal()
      • valueOf
      • values
      • getEnumConstants
  • 实现原理
    • 基本原理
    • 反编译结果
  • 枚举 + 抽象方法
    • 配合客户端
    • 小结
  • 枚举 vs 常量类

引言

如果说泛型是对类型的限制,那么枚举则是对数据范围的限制了

语法

基础语法

public enum WeekDay {
    MON(1,"MONDAY");

    privatE int code;
    private String desc;
    WeekDay(int code,String desc){
        this.code = code;
        this.desc = desc;
    }
}

可以看到,枚举类相较于普通的类,在成员变量和成员方法上几乎没有区别 只是在定义完了成员变量和方法之后,可以在类定义的最前面提前定义好一些枚举对象 其实这只是一个语法糖,枚举对象其实就类似下面这样(详细内容在实现原理小节中有叙述)

    // public static final WeekDay MON = new WeekDay(1,"MONDAY");
    MON(1,"MONDAY");

定义方法

因为枚举其实就是个普通的类,所以我们可以为它添加方法

public enum WeekDay {
    // public static final WeekDay MONDAY = new WeekDay(1,"周一");
    MON(1,"MONDAY");

    privatE int code;
    private String desc;
    WeekDay(int code,String desc){
        this.code = code;
        this.desc = desc;
    }
    // 添加方法
    public int getCode() {
        return this.code;
    }
}

常用方法

枚举原生会有一些常用的方法,这里列举一下

name()

枚举方法的名称

WeekDay.MON.name();  // MON

ordinal()

枚举定义的序号,即枚举定义的顺序,从前到后依次递增

WeekDay.MON.ordinal(); // 0

valueOf

根据值返回枚举对象,默认是根据name返回枚举对象

WeekDay.valueOf("MON").getDesc();  // MONDAY

如果你想根据其他的值获取枚举对象的话,可以自己再写一个工具类

values

Enum没有values方法 枚举对象可以调用values方法,但是父类Enum中却没有这个方法,因为这个方法是编译器在编译时给枚举类加上的 所以当你把枚举向上转型为Enum时,你无法使values方法

WeekDay.values(); 

// 为了方便打印,你可以转成list,另外这里我加了一个周二
Arrays.asList(WeekDay.values());  // [MON,TUE] 

注意:values返回的是原数组的拷贝

getEnumConstants

在上面个的values方法中,我们然无法针对父类Enum使用values方法,但是可以使用getEnumConstants方法,因为这个方法属于Class

WeekDaY[] weekDays = WeekDay.class.getEnumConstants();
// 同样的,你可以转成List
Arrays.asList(weekDays);  // [MON,TUE]

实现原理

基本原理

枚举其实也只是普通的类,但是要搞清楚它是如何完成数据范围限制的

  1. 枚举就是一个常量类(final的),并且构造方法是私有的,所以你没办法新增更多对象
  2. 枚举对象也是静态final的对象,静态保证对象唯一,final保证对象不会被替换

反编译结果

public final class WeekDay extends Enum<WeekDay> {
    public static final /* enum */ WeekDay MON = new WeekDay("MON", 0, 1, "MONDAY");
    privatE int code;
    private String desc;
    private static final /* synthetic */ WeekDaY[] $VALUES;

    public static WeekDaY[] values() {
        return (WeekDaY[])$VALUEs.clone();
    }

    public static WeekDay valueOf(String Name) {
        return Enum.valueOf(WeekDay.class, Name);
    }

    private WeekDay(String String, int n, int code, String desc) {
        super(String, n);
        this.code = code;
        this.desc = desc;
    }

    static {
        $VALUES = new WeekDaY[]{MON};
    }
}

枚举 + 抽象方法

理解原理后,再来看一种枚举的用法,例如现在我们有这样一个需求: 针对不同的工作类型,计算工资(时薪):

  1. 上班 :工资 * 1
  2. 加班:工资 * 2
  3. 请假:工资 * 0

我们可以像下面这样做:

public enum SalaryCouter {
    WORK_SALARY(1) {
        @Override
        public int countSalary(int baseSalary) {
            return baseSalary * 1;
        }
    },
    OVERTIME_SALARY(2) {
        @Override
        public int countSalary(int baseSalary) {
            return baseSalary * 2;
        }
    },
    LEAVE_SALARY(3) {
        @Override
        public int countSalary(int baseSalary) {
            return 0;
        }
    };
    
    privatE int code;
    SalaryCouter(int codE) {
        this.code = code;
    }

    public abstract int countSalary(int baseSalary);

}

测试一下

        int @R_852_10586@lSalary = 8 * SalaryCouter.WORK_SALARY.countSalary(50);

理解原理之后,相信理解这个例子也不困难了,这就相当于是在创建枚举对象时使用了匿名对象的方式

配合客户端

当然了,你这里会吐槽,你这里写死了是哪种工资结算方式,那么前端传过来的时候怎么知道呢? 其实,这里只需要简单的改动下即可

  1. 在枚举类中添加类似valueOf的工具方法
  2. 前端根据工具方法传值即可(例如这里根据code)
  • 添加工具方法 这里只是简单写了下,你也可以使用@H_412_61@map存储code和对应的枚举实例进行缓存
public static SalaryCouter getSalaryCounter(int codE) {
        switch (codE) {
            case 1:
                return WORK_SALARY;
            case 2:
                return OVERTIME_SALARY;
            case 3:
                return LEAVE_SALARY;
            default:
                return WORK_SALARY;
        }
    }
  • 测试一下
// 这里的1就是前端对应传过来的值
int @R_852_10586@lSalary2 = SalaryCouter.getSalaryCounter(1)
                                        .countSalary(50);

小结

这样写的好处是,未来不论增加多少种工资结算的方式,客户端的代码都不需要变动

枚举 vs 常量类

枚举的优点:

  1. 因为是通过对象保存的,所以说可以存储更多信息,特别是需要绑定到一起的信息,例如状态码和状态信息
  2. 枚举 + 抽象方法:可以针对某一个功能(例如计算工资的方式)提供有限的实现方式(枚举无法被继承,你也无法新建一个枚举对象)

大佬总结

以上是大佬教程为你收集整理的Java基础 - 枚举全部内容,希望文章能够帮你解决Java基础 - 枚举所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。