语法糖甜不甜?巧用枚举实现“状态”转换限制(三)

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。

上篇文章中我们翻看了枚举类的反编译源码,本文我们来聊一下枚举类的具体使用规则!

Enum

Enum 是所有 Java 语言枚举类型的公共基类,实现了 Comparable 和 Serializable 接口。它包含 final 类型的 name 和 ordinal (此枚举常量的序号,从0开始)属性,下面我们来了解下它的方法

  • protected Enum(String name, int ordinal);——构造方法;
  • public String toString();——返回 name 字段,即枚举定义枚举变量的字符串;
  • protected final Object clone();——抛出 CloneNotSupportedException 异常,保证枚举类永远不会被克隆;
  • public final Class getDeclaringClass();——返回与此枚举常量的枚举类型对应的类对象;
  • protected final void finalize();—— 枚举类不能有 finalize 方法;
  • readObject(ObjectInputStream in);& readObjectNoData();—— 抛出InvalidObjectException 异常,防止默认反序列化;

扩展

  1. 枚举类中可以自定义属性

    自定义的属性值最好用 private final 修饰,防止生成的 set 方法在使用时修改属性值,使代码更加安全。

  2. 枚举类中可以自定义构造函数

    构造函数必须为 private 修饰,防止在别处声明此类对象。

  3. 枚举类可以自定义方法,枚举项可以选择性覆盖自定义的方法。

    public enum OrderStatus{
        NO_PAY("未支付",0),
        PAY("已支付",1){
            @Override
            public void printOrderStatus() {
                System.out.println("已支付");
            }
        },
        REFUNDING("退款中",2),
        REFUNDED("退款成功",3),
        FAIL_REFUNDED("退款失败",4),
        ;
    
        private final String name;
        private final int status;
    
        private OrderStatus(String name,int status){
            this.name = name;
            this.status = status;
        }
    
        public void printOrderStatus(){
            System.out.println("打印订单状态");
        }
    }
    
    
    public class EnumTest {
        public static void main(String[] args) {
            OrderStatus.PAY.printOrderStatus();
            OrderStatus.NO_PAY.printOrderStatus();
        }
    }
    复制代码

枚举类也可以有抽象方法,但是枚举项必须重写该方法。

  1. 枚举类实现接口

    扫描二维码关注公众号,回复: 13165089 查看本文章

    与普通类一样,实现接口的时候需要实现接口的抽象方法,也可以让枚举类的不同对象实现不同的行为。

//定义一个接口
public interface Order {
    void printOrderStatus();
}

//枚举类实现该接口
public enum OrderStatus implements Order{
    NO_PAY("未支付",0){
        @Override
        public void printOrderStatus() {
            System.out.println("未支付");
        }
    },
    PAY("已支付",1){
        @Override
        public void printOrderStatus() {
            System.out.println("已支付");
        }
    },
    REFUNDING("退款中",2){
        @Override
        public void printOrderStatus() {
            System.out.println("退款中");
        }
    },
    REFUNDED("退款成功",3){
        @Override
        public void printOrderStatus() {
            System.out.println("退款成功");
        }
    },
    FAIL_REFUNDED("退款失败",4){
        @Override
        public void printOrderStatus() {
            System.out.println("退款失败");
        }
    },
    ;

    private final String name;
    private final int status;

    private OrderStatus(String name,int status){
        this.name = name;
        this.status = status;
    }
}
复制代码

此时查看编译后的文件,会发现除了生成 OrderStatus.class 文件之外,还生成了多个 .class 文件:

它们是 OrderStatus.class 中生成的匿名内部类的文件。

了解了枚举类的使用规则之后,我们可以利用枚举类来实现一个订单状态转换的小案例。如果你有不同的意见或者更好的idea,欢迎联系阿Q,添加阿Q可以加入技术交流群参与讨论呦!

猜你喜欢

转载自juejin.im/post/7016862803461931044