zoukankan      html  css  js  c++  java
  • java基础-enum

    jdk5中加入了enum类型,那么他是怎样一种结构呢,通过反编译enum可以一窥。

    1 public enum Status{
    2       OK, ERROR               
    3 }

    反编译上述代码,可知enum在编译后被转换成了一个被public final修饰的、继承了java.lang.Enum的类型,看来enum只不过是一颗语法糖罢了。

    OK、ERROR转换成了public static finally Status类型的类变量,还自动生成了一个public static Status[]类型的数组。

    OK、ERROR既然是static final类型的,一定在声明处就赋了值,那么我们来看类初始化方法。如下图,可以看到在创建OK、ERROR时,调用了Status(String, int)构造器,这个构造器是java.lang.Enum中唯一的一个构造器,而此时我们并没有显示调用该构造器,这些都是编译期帮我们做的。

    那么,如果我们自定义enum会是怎样一番景象呢?定义enum如下

     1 public enum Status {
     2     OK(1,"ok"), BAD(2,"bad");
     3 
     4     private int code;
     5     private String msg;
     6     private Status(int a, String b) {
     7         this.code = a;
     8         this.msg = b;
     9     }
    10     public int code() {
    11         return code;
    12     }
    13     public String msg() {
    14         return msg;
    15     }
    16 }

    反编译后发现,与之前不同的地方只在于创建OK、ERROR时所调用的构造器,前例调用了java.lang.Enum的唯一构造器,本例所调用的构造器既不是Enum的唯一构造器Enum(String, int),也不是我们自定义的Status(int, String)构造器,而是二者融合后的一个构造器Status(String, int, int, String),但在class字节码中并没有该构造器的实现,并且自定义的Status构造器也没有出现。

    通过以上分析可知,enum中的OK、ERROR其实就是Enum子类中的类变量,这些类变量在类初始化时通过调用特殊的构造器被赋值。由于java中是单继承的,让enum显示继承类是不可能了,但是可以实现接口。下例的代码中,SPECIAL实现了自己的StatusInterface接口,这也比较好理解,像SPECIAL(3, "special")这种写法,其实就是在调用(特殊的)构造器创建一个名为SPECIAL的类变量(SPECIAL这种写法与SPECIAL()等价),那么SPECIAL(3, "special"){...}其实就是实例化一个Status的代理类(子类)。

     1 public enum Status implements StatusInterface{
     2     OK(1,"ok"), BAD(2,"bad"), SPECIAL(3, "special"){
     3         @Override
     4         public void statusInterface() {
     5             System.out.println("special status");
     6         }
     7     };
     8     private int code;
     9     private String msg;
    10     private Status(int a, String b) {
    11         this.code = a;
    12         this.msg = b;
    13     }
    14     @Override
    15     public void statusInterface() {
    16         System.out.println("normal status");
    17     }
    18     public int code() {
    19         return code;
    20     }
    21     public String msg() {
    22         return msg;
    23     }
    24 }

    参考:https://unmi.cc/understand-java-enum-with-bytecode/

  • 相关阅读:
    生产环境之Nginx高可用方案
    MySQL主从同步配置
    SpringBoot整合MyBatisPlus配置动态数据源
    循环有序数组,查找值
    数组任意取三个数中乘积最大值
    多线程输出123以及有序输出1-75
    有序数组取中值
    RocketMQ原理及源码解析
    docker基础常用命令
    项目常用命令
  • 原文地址:https://www.cnblogs.com/holoyong/p/7249352.html
Copyright © 2011-2022 走看看