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

178 阅读2分钟

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

上篇文章中我们已经了解了语法糖和枚举的基本概念,本文我们就使用反编译软件来分析一下枚举类的反编译源码!

反编译

我们可以先通过 javac 命令或者 IDEA 的编译功能将OrderStatus.java 编译为OrderStatus.class 字节码文件,然后用DJ Java Decompiler 反编译器对 .class 文件进行反编译。

如果需要 DJ Java Decompiler 反编译器的小伙伴可以私信阿Q获取!

public final class OrderStatus extends Enum
{

    //该方法会返回包括所有枚举变量的数组,可以方便的用来做循环。
    public static OrderStatus[] values()
    {
        return (OrderStatus[])$VALUES.clone();
    }

    //根据传入的字符串,转变为对应的枚举变量。
    //前提是传的字符串和定义枚举变量的字符串一抹一样,区分大小写。
    //如果传了一个不存在的字符串,那么会抛出异常。
    public static OrderStatus valueOf(String name)
    {
        return (OrderStatus)Enum.valueOf(com/itcast/java/enumpack/OrderStatus, name);
    }

    private OrderStatus(String s, int i)
    {
        super(s, i);
    }

    public static final OrderStatus NO_PAY;
    public static final OrderStatus PAY;
    public static final OrderStatus REFUNDING;
    public static final OrderStatus REFUNDED;
    public static final OrderStatus FAIL_REFUNDED;
    private static final OrderStatus $VALUES[];

    static 
    {
        NO_PAY = new OrderStatus("NO_PAY", 0);
        PAY = new OrderStatus("PAY", 1);
        REFUNDING = new OrderStatus("REFUNDING", 2);
        REFUNDED = new OrderStatus("REFUNDED", 3);
        FAIL_REFUNDED = new OrderStatus("FAIL_REFUNDED", 4);
        $VALUES = (new OrderStatus[] {
            NO_PAY, PAY, REFUNDING, REFUNDED, FAIL_REFUNDED
        });
    }
}

如源码所示:

  • 编译器会自动帮我们创建一个 final 类型的类继承 Enum 类,所以枚举类不能被继承。
  • 会自动生成私有构造方法,当然我们也可以定义构造方法,但必须是私有的,这样就不能在别处声明此类的对象了。
  • 枚举项会被自动添加 public static final 修饰,并定义为 OrderStatus 类型,并在静态代码块中被初始化。
  • 并提供了 values()valueOf(String name) 的静态方法。

我们定义的枚举变量实际上是编译器帮我们自动生成了构造函数。

所有枚举类都是 Enum 的子类,枚举类可以实现一个或多个接口。

通过查看枚举类的反编译源码,我们对枚举类的底层实现有了进一步的认识,下篇文章我们来聊一下枚举类的具体使用规则。如果你有不同的意见或者更好的idea,欢迎联系阿Q,添加阿Q可以加入技术交流群参与讨论呦!