在阅读《阿里巴巴Java开发手册》时,发现有一条关于二方库依赖中接口返回值不允许使用枚举类型的规约,具体内容如下:

在谈论为什么之前先来科普下什么是二方库,二方库也称作二方包,一般指公司内部发布到中央仓库,可供公司内部其他应用依赖的库(jar 包)。

那么一方库便是本工程内部子项目模块依赖的库;三方库为公司之外的开源库,比如像 fastjson、easyexcel 这种。

下面我们就通过一个例子来看下为什么阿里巴巴不允许返回枚举类型或者包含枚举类型的 POJO 对象。

比如星巴克提供了 0.0.1 版本的二方库,定义了一个 Starbucks 类,里面包含了枚举类型的 SizeEnum,里面分别是中杯、大杯、特大杯。

public class Starbucks implements Serializable {
private Long id;
private String name;
private Integer capacity;
private SizeEnum sizeEum;
} public enum SizeEnum {
TALL(1),
GRANDE(2),
VENTI(3)
}

定义了一个服务类,实现了根据 id 获取星巴克的方法:

public class StarbucksImpl implements StarbucksService {
public Starbucks getStarbucksById(Long id) {
Starbucks starbucks = new Starbucks();
starbucks.setId(1L);
starbucks.setName("Latte");
starbucks.setCapacity(360);
starbucks.setSizeEnum(SizeEnum.TALL);
return starbucks;
}
}

然后,星巴克的门店引入 0.0.1 这个版本 jar 包,然后卖的好好的:

public class StarbucksDemo {
@Resource
private StarbucksService starbucksService; public void getStarbucks() {
Starbucks starbucks = starbucksService.getStarbucksById(1L);
System.out.println(starbucks);
}
}

有一天,老罗说要那个中等大小的中杯拿铁,但是服务员说那是大杯,经过一番争论,罗老师很是生气。

于是星巴克升级到了 0.0.2 版本二方库,在枚举类 SizeEnum 中新增了小杯,升级后的枚举类如下:

public enum SizeEnum {
TALL(1),
GRANDE(2),
VENTI(3),
SHORT(4)
}

同时服务类的接口方法也做了相应修改:

public class StarbucksImpl implements StarbucksService {
public Starbucks getStarbucksById(Long id) {
Starbucks starbucks = new Starbucks();
starbucks.setId(1L);
starbucks.setName("Latte");
starbucks.setCapacity(240);
starbucks.setSizeEnum(SizeEnum.SHORT);
return starbucks;
}
}

由于星巴克的门店比较多,有的还不知道这个新加的需求,因此返回结果中出现了 SHORT,但是 0.0.1 版本的二方库中没有小杯啊,所以就出问题了,也就是序列化失败。

通过这个例子,我相信大家对枚举类型作为返回结果有了一定的理解,下面引用孤尽大佬在知乎的回答:

由于升级原因,导致双方的枚举类不尽相同,在接口解析,类反序列化时出现异常。

Java 中出现的任何元素,在 Gosling 的角度都会有背后的思考和逻辑(尽管并非绝对完美,但 Java 的顶层抽象已经是天才级了),比如:接口、抽象类、注解、和本文提到的枚举。枚举有好处,类型安全,清晰直接,还可以使用等号来判断,也可以用在 switch 中。它的劣势也是明显的,就是不要扩展。可是为什么在返回值和参数进行了区分呢,如果不兼容,那么两个都有问题,怎么允许参数可以有枚举。当时的考虑,如果参数也不能用,那么枚举几乎无用武之地了。参数输出,毕竟是本地决定的,你本地有的,传送过去,向前兼容是不会有问题的。但如果是接口返回,就比较恶心了,因为解析回来的这个枚举值,可能本地还没有,这时就会抛出序列化异常。

比如:你的本地枚举类,有一个天气 Enum:SUNNY, RAINY, CLOUDY,如果根据天气计算心情的方法:guess(WeatcherEnum xx),传入这三个值都是可以的。返回值:Weather guess(参数),那么对方运算后,返回一个 SNOWY,本地枚举里没有这个值,傻眼了。

总结

本文通过一个实例让大家理解到枚举类型作为返回结果的坑,大家可以使用基本类型或者基本类型包装类来替换掉枚举类型就可以避免掉这么问题了。

大家对于这条规约​有什么看法,也欢迎留言讨论。​

最好的关系就是互相成就,大家的在看、转发、留言三连就是我创作的最大动力。

参考

《Java开发手册》泰山版

https://www.zhihu.com/question/52760637/answer/338584321

为什么阿里巴巴Java开发手册中强制要求接口返回值不允许使用枚举?的更多相关文章

  1. 为什么阿里巴巴Java开发手册中强制要求整型包装类对象值用 equals 方法比较?

    在阅读<阿里巴巴Java开发手册>时,发现有一条关于整型包装类对象之间值比较的规约,具体内容如下: 这条建议非常值得大家关注, 而且该问题在 Java 面试中十分常见. 还需要思考以下几个 ...

  2. 为什么阿里巴巴Java开发手册中强制要求不要在foreach循环里进行元素的remove和add操作?

    在阅读<阿里巴巴Java开发手册>时,发现有一条关于在 foreach 循环里进行元素的 remove/add 操作的规约,具体内容如下: 错误演示 我们首先在 IDEA 中编写一个在 f ...

  3. 为什么阿里巴巴Java开发手册中不建议在循环体中使用+进行字符串拼接?

    之前在阅读<阿里巴巴Java开发手册>时,发现有一条是关于循环体中字符串拼接的建议,具体内容如下: 那么我们首先来用例子来看看在循环体中用 + 或者用 StringBuilder 进行字符 ...

  4. 为什么阿里巴巴Java开发手册中不允许魔法值出现在代码中?

    在阅读<阿里巴巴Java开发手册>时,发现有一条关于关于常量定义的规约,具体内容如下: 图中的反例是将数据缓存起来,并使用魔法值加链路 id 组成 key,这就可能会出现其他开发人员在复制 ...

  5. 阿里巴巴Java开发手册中的DO、DTO、BO、AO、VO、POJO定义

    分层领域模型规约: DO( Data Object):与数据库表结构一一对应,通过DAO层向上传输数据源对象. DTO( Data Transfer Object):数据传输对象,Service或Ma ...

  6. 《阿里巴巴Java开发手册》代码格式部分应用——idea中checkstyle的使用教程

    <阿里巴巴Java开发手册>代码格式部分应用--idea中checkstyle的使用教程 1.<阿里巴巴Java开发手册> 这是阿里巴巴工程师送给各位软件工程师的宝典,就像开车 ...

  7. 为什么阿里巴巴开发手册中强制要求 POJO 类使用包装类型?NPE问题防范

    封面:学校内的秋天 背景:写这个的原因,也是我这两天凑巧看到的,虽然我一直有 alibaba Java 开发手册,也看过不少次,但是一直没有注意过这个问题 属于那种看过,但又没完全看过 一起来看看吧冲 ...

  8. 阿里巴巴Java开发手册———个人追加的见解和补充(一)

    先上干货,<阿里巴巴Java开发手册>的下载地址 https://yq.aliyun.com/articles/69327?spm=5176.100239.blogcont69327.15 ...

  9. 阿里巴巴Java开发手册评述

    2016年底的时候阿里巴巴公开了其在内部使用的Java编程规范.随后进行了几次版本修订,目前的版本为v1.0.2版.下载地址可以在其官方社区-云栖社区https://yq.aliyun.com/art ...

随机推荐

  1. 类文件结构——深入理解Java虚拟机 笔记三

    在之前的笔记中记录过,Java程序变成可执行文件的步骤是:源代码-->经过编译变成class文件-->经过JVM虚拟机变成可执行的二进制文件.因此,为了对JVM执行程序的过程有一个好的了解 ...

  2. nginx均衡负载

    一直在担心session 问题,结果试了2个web 论坛,discuz 和phpbb ,前面用nginx 均衡负载,后端是apache httpd +php ,mysql 用同一个,修改一下confi ...

  3. 轻松解决python异常处理,你值得拥有

    目录 python中常见的异常信息+处理方法 常见异常类型 异常处理 python中常见的异常信息+处理方法 常见异常类型 异常类名 功能描述 Exception 所有异常的基类 ValueError ...

  4. DPDK Hash Library原理(学习笔记)

    0 前言 本文主要翻译至DPDK的官方编程指南,在谷歌翻译的基础上根据自己的理解做了一些修改.网上搜索的很多中文翻译大多是翻译后直接黏贴上来,有时候连语句都读不通.希望本文能够对你有所帮助. 1 介绍 ...

  5. Canvas 画圆

    原文地址:http://hi.baidu.com/lj2tj/item/557d8d1a65adfa721009b58b --------------------------------------- ...

  6. 都说变量有七八种,到底谁是 Java 的亲儿子

    网上罗列了很多关于变量的理解,良莠不齐,不知道哪些是对的,哪些是错的,所以笔者就这些博客和自己的理解写出这篇文章,如果有不对的地方,希望读者能够指正,感谢. 变量是我们经常用到的一种,我在刚学 Jav ...

  7. Fabric进阶(一)—— 修改组织和通道的名称

    组织(Org)和通道(Channel)的名称是fabric网络比较重要的两个配置参数,在fabric提供的示例中都已经设置好了这两个参数,一般组织名为"Org1"和"Or ...

  8. vue-codemirror + Java Compiler实现Java Web IDE

    背景 最近同事告诉我一个很有趣的需求:让用户(应用场景中,一般为其他开发者)自己填入Java代码片段,代码片段的内容为已经规定好的模板类的继承类,实现模板类定义的方法.我们的项目要实现动态编译代码片段 ...

  9. 关于lua的那些事

    1.lua是一个脚本语言,由巴西里约热内卢天主教大学Roberto Ierusalimschy.Waldemar Celes 和 Luiz Henrique de Figueiredo三人所组成的研究 ...

  10. [nginx报错问题]reload时报错:nginx: [error] invalid PID number "" in ...

    错误 第一次探索nginx,执行以下命令时: nginx -s reload 报出错误: nginx: [error] invalid PID number "" in ... * ...