java中的枚举类型 Enum

目录

1、枚举类型能实现枚举,编号

2、枚举的使用方法

3、枚举的利弊

4、总结


参考文章:https://zhuanlan.zhihu.com/p/51296740

1、枚举类型能实现枚举,编号

  • 定义常量,并且可以定义常量的格式(即可以定义多个具有一定数据结构的变量);
  • 自动对枚举的多个常量编号;

比如:

定义一个指令的枚举类,枚举7种指令,每个指令包含指令目标target、指令动作action。

public enum CommandType {
    CPU_LOAD("cpu", "load"),
    DISK_FILL("disk", "fill"),
    MEM_LOAD("mem", "load"),
    NETWORK_DELAY("network", "delay"),
    NETWORK_LOSS("network", "loss"),
    DESTROY("nil", "nil"),
    STATUS("nil", "nil");

    private String target;
    private String action;

    CommandType(String target, String action) {
        this.target = target;
        this.action = action;
    }

    public String getTarget() {
        return target;
    }

}

2、枚举的使用方法

参考文章:Java 枚举(enum) 详解7种常见的用法


3、枚举的使用注意事项

参考文章:Java枚举什么不好,《阿里巴巴JAVA开发手册》对于枚举规定的考量是什么?

1)枚举可以用于参数和返回值。但是考虑到现在的微服务架构,服务端和客户端之间的接口可能不能同时更新,因此如果把枚举作为返回值的话,可能会导致没有相应枚举类的一方出现反序列化的问题;与此同时,如果枚举作为接口中的参数,是可以的,原因参考如下。

作者:北南
链接:https://www.zhihu.com/question/52760637/answer/349380925
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
 

使用枚举的确会带来扩展兼容性的问题,这点很多答主都说的很好了,我就说一下为什么参数上可以使用枚举的原因吧。

咱们先假定对枚举的扩展只是新增值,而不是减少值。比如说性别中本来是男和女,现在要增加一个transgender, 但我们极少极少会有需求说,把性别中的已有男或者女去掉。(我觉得这个假设是参数可以使用枚举型的前提)

在这个假定下如果我们在接口中使用枚举型,如孤尽兄在java开发手册中所述,分为参数和返回值两种情况。

不管是微服务之间的互相调用,还是手机客户端到服务器的调用,在不停机的情况下,服务器端和客户端是很难一起更新的,往往我们是服务器端先来支持新feature,然后再来逐步更新客户端。我想孤尽兄说参数可以使用枚举型,也是基于这种更新升级方式。

因为服务器端如果突然开始返回transgender这个新性别,客户端吃不进去(反序列化不了),客户端就炸了。但如果服务器端只是在参数上开始接受新性别,那就不怕老客户端,反正老客户端还在那里继续发送男和女这两种性别,服务器端都认识,就不会出错。两边可以一直相安无事,慢慢等所有客户端都升级。

但是呢,如果我们用string来代替枚举,服务器端贸然返回一个新的值,客户端不知道怎么处理,也可能会产生其他问题,比如说钱算错了之类业务层面的问题。所以客户端代码可能要先更新一点,让其能处理这个新的值。我觉得阿里把这个标准放在手册里,也是多年的经验教训,两害相权取其轻吧。因为很多应用是没法强制客户端一起更新的。尤其是手机移动客户端,ios可能还要审核,很难做到客户端和服务器端同步更新。如果是微服务,也很难在不停机的情况下,把通过枚举耦合两个微服务一起更新。


4、总结

枚举,就是把已知的全部罗列出来。作为二方/三方库的提供者,我支持什么,你们就是用什么,这样是安全的。库版本升级后接口支持了更多,用户不知道情况下自然不会使用,接口不支持的参数用户根本不会传。所以枚举作为接口的输入参数,一般不会出问题。

但作为返回值,情况就反过来了。接口将枚举类的返回值返给二方/三方库,用户作为消费者,根本没有办法反序列化接口返回的枚举类,那肯定就会出错。

 

猜你喜欢

转载自blog.csdn.net/Longtermevolution/article/details/108399737