美文网首页
关于java枚举和常量类

关于java枚举和常量类

作者: haiyong6 | 来源:发表于2021-01-18 14:52 被阅读0次

    既然有了常量类为何还需要用枚举,时常思考枚举的意义。

    应用场景:

    对于在java代码中出现的需要解释其意义的常量,通常不会直接用数字或符号去表示(不清晰,不利于业务理解与管理),而是需要建一个常量类声明一个常量来统一管理。
    比如现在有四个状态,分别是待升级,正在升级,升级失败,升级完成,这些状态在项目中通常使用数字来表示,比如分别定义为-1,3,4,5

    这种情况下,我们单独定义一个常量类来统一管理需要满足以下几个特征:
    1.可读性,一眼看到就知道是什么状态,而不是空洞洞的数字
    2.不可更改性,这些定义好的东西,绝对不能被代码随意更改,所以会使用static final来修饰
    3.可以方便的拿到定义好的数字和文字描述
    4.必要时候可以拿到所有属性有序遍历,但是不可被代码更改。

    基于以上几个特征我们通常会这样新建一个常量类:

    package com.ly.mp.ota.common;
    
    import java.util.Collections;
    import java.util.LinkedHashMap;
    import java.util.Map;
    
    public class UpgradeRecordConstant {
        
        public static final String TOBE_UPGRADED = "-1";
        public static final String UPGRADING = "3";
        public static final String FAILURE = "4";
        public static final String SUCCESS = "5";
        private static final Map<String, String> upgradeRecordNameMap = new LinkedHashMap<String, String>();
        static {
            upgradeRecordNameMap.put(TOBE_UPGRADED, "待升级");
            upgradeRecordNameMap.put(UPGRADING, "正在升级");
            upgradeRecordNameMap.put(FAILURE, "升级失败");
            upgradeRecordNameMap.put(SUCCESS, "升级完成");
        }
        
        public static String getNameByStatus(String status) {
            return null == upgradeRecordNameMap.get(status) ? "" : upgradeRecordNameMap.get(status);
        }
        
        public static Map<String, String> getUpgradeRecordNameMap(){
            return Collections.unmodifiableMap(upgradeRecordNameMap);
        }
        
        public static void main(String[] args) {
            System.out.println(UpgradeRecordConstant.getNameByStatus(UpgradeRecordConstant.FAILURE));
            System.out.println(UpgradeRecordConstant.FAILURE);
            System.out.println(UpgradeRecordConstant.getUpgradeRecordNameMap());
        }
    }
    
    

    上面代码中声明的几个状态都用static final修饰,所以不能被再次赋值,保证了常量的安全性,声明一个private static final类型的有序的LinkedHashMap,在初始化代码的时候赋值,并提供getNameByStatus方法获取此LinkedHashMap中的属性值,提供getUpgradeRecordNameMap方法来可以直接获取此map,Collections.unmodifiableMap来保证此map不可更改。运行main测试方法遍历结果如下:

    升级失败
    4
    {-1=待升级, 3=正在升级, 4=升级失败, 5=升级完成}
    

    如此,可以用类.属性直接拿到状态值,用getNameByStatus方法来获取值描述。

    可以看到如果用常量类实现这些还是需要写一些代码的,所以在jdk1.5之后,java出现了枚举,它的出现就是为了让类似我们这种需求更加简单直观。

    下面用枚举实现同样的功能:

    package com.ly.mp.ota.common;
    
    public enum UpgradeRecordStatus {
        
        TOBE_UPGRADED("待升级", "-1"),
        UPGRADING("正在升级", "3"),
        FAILURE("升级失败", "4"),
        SUCCESS("升级完成", "5");
        
        private String name;
        private String status;
        
        private UpgradeRecordStatus(String name, String status) {
            this.name = name;
            this.status = status;
        }
    
        public String getStatus() {
            return status;
        }
        
        public String getName() {
            return name;
        }
        public static void main(String[] args) {
            System.out.println(UpgradeRecordStatus.FAILURE.getName());
            System.out.println(UpgradeRecordStatus.FAILURE.getStatus());
            UpgradeRecordStatus[] arr = UpgradeRecordStatus.values();
            for(UpgradeRecordStatus s : arr) {
                System.out.println(s.getName() + " " + s.getStatus());
            }
        }
    }
    

    运行main方法结果如下:

    升级失败
    4
    待升级 -1
    正在升级 3
    升级失败 4
    升级完成 5
    

    以上代码可以看出,用枚举实现同样的功能,代码量更少,枚举是专门为这样的场景设计,扩展性也比用常量好的多,现在只是id和name这两个属性,如果想要更多,枚举也只是在后面的构造方法里加多几个就可以了,而常用量可能要写更多的map才行。

    枚举是已经继承了java.lang.Enum类的,所以不可再继承其他类,除此之外,他通常拥有普通java类的特点:可以有自己的成员变量,成员方法,静态方法、静态变量等,也能实现其他的接口,所以也许有人会问那枚举可以有set方法吗?从语法上是没有问题的,可以设置set方法来改变变量的值,但是通常不会这样做,因为毕竟有枚举的意义就是要保证每个属性都是常量,不可被更改的,所以在实际运用中最好不要设置set方法。

    相关文章

      网友评论

          本文标题:关于java枚举和常量类

          本文链接:https://www.haomeiwen.com/subject/nfcbaktx.html