• java中枚举实现原理


    介绍

    枚举是java5新增的特性,我们可以用来替代以前用常量完成的功能。java对枚举的支持还有EnumSet,EnumMap等工具类。

    使用

    public enum UserGenderEnum {
      MALE("0", "男"),
      FEMALE("1", "女"),
      NOT_KNOWN("2", "未知");
    
      private final String code;
      private final String info;
    
      UserGenderEnum(String code, String info) {
        this.code = code;
        this.info = info;
      }
    
      public String getCode() {
        return code;
      }
    
      public String getInfo() {
        return info;
      }
    }
    
    public class Client {
      public static void main(String[] args) {
        UserGenderEnum[] userGenderEnums = UserGenderEnum.values();
        for (UserGenderEnum genderEnum : userGenderEnums) {
          System.out.println("enum:" + genderEnum + "," + genderEnum.name() + "," + genderEnum.ordinal());
        }
        System.out.println(UserGenderEnum.valueOf("MALE"));
      }
    }
    

    输出结果为

    enum:MALE,MALE,0
    enum:FEMALE,FEMALE,1
    enum:NOT_KNOWN,NOT_KNOWN,2
    MALE
    

    我们看一下枚举反编译后的结果,如何反编译看上一篇文章

    public final class UserGenderEnum extends Enum<UserGenderEnum> {
        public static final /* enum */ UserGenderEnum MALE = new UserGenderEnum("MALE", 0, "0", "u7537");
        public static final /* enum */ UserGenderEnum FEMALE = new UserGenderEnum("FEMALE", 1, "1", "u5973");
        public static final /* enum */ UserGenderEnum NOT_KNOWN = new UserGenderEnum("NOT_KNOWN", 2, "2", "u672au77e5");
        private final String code;
        private final String info;
        private static final /* synthetic */ UserGenderEnum[] $VALUES;
    
        public static UserGenderEnum[] values() {
            return (UserGenderEnum[])$VALUES.clone();
        }
    
        public static UserGenderEnum valueOf(String name) {
            return Enum.valueOf(UserGenderEnum.class, name);
        }
    
        private UserGenderEnum(String string, int n, String code, String info) {
            super(string, n);
            this.code = code;
            this.info = info;
        }
    
        public String getCode() {
            return this.code;
        }
    
        public String getInfo() {
            return this.info;
        }
    
        static {
            $VALUES = new UserGenderEnum[]{MALE, FEMALE, NOT_KNOWN};
        }
    }
    

    枚举类默认继承Enum抽象类,这也是枚举不能继承其他类的原因。编译器帮我们创建了3个静态实例,并将构造器设为私有,在我们的构造参数基础上增加了name和ordinal两个参数,indinal可以看做实例的索引。接下来我们看一下valueOf方法的实现原理,

    这个方法是编译器帮我们创建的,反编译后才可以看到,

    实际上调用的是Enum内部的方法,

    继续跟到Class类


    终于看到了最终实现,可以看到Class还是调用了UserGenderEnum的values方法,上面可以看到values方法返回的是实例的数组,兜兜转转有回到了UserGenderEnum。
    接下来看一下switch对枚举的支持,

    public class Client {
      public static void main(String[] args) {
        UserGenderEnum male = UserGenderEnum.MALE;
        switch (male) {
          case MALE:
            System.out.println("male");
            break;
          case FEMALE:
            System.out.println("female");
            break;
          case NOT_KNOWN:
            System.out.println("not_known");
            break;
        }
      }
    }
    

    反编译结果为

    public class Client {
        public static void main(String[] args) {
            UserGenderEnum male = UserGenderEnum.MALE;
            switch (male.ordinal()) {
                case 1: {
                    System.out.println("male");
                    break;
                }
                case 2: {
                    System.out.println("female");
                    break;
                }
                case 3: {
                    System.out.println("not_known");
                }
            }
        }
    }
    

    可以看到最终还是转成了int类型。

  • 相关阅读:
    Asp.Net Core MVC + Code First + Mysql 项目创建以及相关配置
    linux安装 docker compose v2
    压缩、解压 解决 客户端查询大批量数据时等待时间过长的问题
    c# 通过经纬度 查询地址、区域信息
    excel 文件转 dataset ,jqgrid 中 模糊查询与下拉联动的实现
    jqgrid mvc 导出excel
    SQL学习笔记三表的字段操作
    SQL学习笔记高级教程
    安装docker
    SQL学习笔记一数据类型
  • 原文地址:https://www.cnblogs.com/strongmore/p/13282655.html
Copyright © 2020-2023  润新知