为什么阿里巴巴Java开发手册中强制要求接口返回值不允许使用枚举?
在阅读《阿里巴巴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开发手册》泰山版
为什么阿里巴巴Java开发手册中强制要求接口返回值不允许使用枚举?的更多相关文章
- 为什么阿里巴巴Java开发手册中强制要求整型包装类对象值用 equals 方法比较?
在阅读<阿里巴巴Java开发手册>时,发现有一条关于整型包装类对象之间值比较的规约,具体内容如下: 这条建议非常值得大家关注, 而且该问题在 Java 面试中十分常见. 还需要思考以下几个 ...
- 为什么阿里巴巴Java开发手册中强制要求不要在foreach循环里进行元素的remove和add操作?
在阅读<阿里巴巴Java开发手册>时,发现有一条关于在 foreach 循环里进行元素的 remove/add 操作的规约,具体内容如下: 错误演示 我们首先在 IDEA 中编写一个在 f ...
- 为什么阿里巴巴Java开发手册中不建议在循环体中使用+进行字符串拼接?
之前在阅读<阿里巴巴Java开发手册>时,发现有一条是关于循环体中字符串拼接的建议,具体内容如下: 那么我们首先来用例子来看看在循环体中用 + 或者用 StringBuilder 进行字符 ...
- 为什么阿里巴巴Java开发手册中不允许魔法值出现在代码中?
在阅读<阿里巴巴Java开发手册>时,发现有一条关于关于常量定义的规约,具体内容如下: 图中的反例是将数据缓存起来,并使用魔法值加链路 id 组成 key,这就可能会出现其他开发人员在复制 ...
- 阿里巴巴Java开发手册中的DO、DTO、BO、AO、VO、POJO定义
分层领域模型规约: DO( Data Object):与数据库表结构一一对应,通过DAO层向上传输数据源对象. DTO( Data Transfer Object):数据传输对象,Service或Ma ...
- 《阿里巴巴Java开发手册》代码格式部分应用——idea中checkstyle的使用教程
<阿里巴巴Java开发手册>代码格式部分应用--idea中checkstyle的使用教程 1.<阿里巴巴Java开发手册> 这是阿里巴巴工程师送给各位软件工程师的宝典,就像开车 ...
- 为什么阿里巴巴开发手册中强制要求 POJO 类使用包装类型?NPE问题防范
封面:学校内的秋天 背景:写这个的原因,也是我这两天凑巧看到的,虽然我一直有 alibaba Java 开发手册,也看过不少次,但是一直没有注意过这个问题 属于那种看过,但又没完全看过 一起来看看吧冲 ...
- 阿里巴巴Java开发手册———个人追加的见解和补充(一)
先上干货,<阿里巴巴Java开发手册>的下载地址 https://yq.aliyun.com/articles/69327?spm=5176.100239.blogcont69327.15 ...
- 阿里巴巴Java开发手册评述
2016年底的时候阿里巴巴公开了其在内部使用的Java编程规范.随后进行了几次版本修订,目前的版本为v1.0.2版.下载地址可以在其官方社区-云栖社区https://yq.aliyun.com/art ...
随机推荐
- java ->String、StringBuffer、StringBuilder三者之间的区别
1.首先说运行速度,速度由快到慢排列:StringBuilder > StringBuffer > String String最慢的原因: String为字符串常量,而StringBuil ...
- XLNet看这篇文章就足以!
文章链接:https://arxiv.org/pdf/1906.08237.pdf 代码链接:英文--https://github.com/zihangdai/xlnet 中文--https ...
- Redux:action
引入redux之后,代码中对组件state的更新变得规范而可控,不再是分散的一句句setState,而是将组件的state集合在一个单例store中,并以引用的方式获取各自的state. 对于stat ...
- 基于 abp vNext 和 .NET Core 开发博客项目 - 统一规范API,包装返回模型
上一篇文章(https://www.cnblogs.com/meowv/p/12916613.html)使用自定义仓储完成了简单的增删改查案例,有心的同学可以看出,我们的返回参数一塌糊涂,显得很不友好 ...
- 关于MySQL数据被删除后空间重用的问题实验
以前知道,MySQL在通过delete语句删除数据后,空间并不会被腾出,而只是在数据文件中被标记为已删除,除非执行optimize table.前两天听说,虽然delete数据后硬盘空间不会被腾出,但 ...
- Shone.Math开源系列2 — 实数类型(含分数和无理数)的实现
Shone.Math开源系列2 实数类型(含分数和无理数)的实现 作者:Shone 声明:原创文章欢迎转载,但请注明出处,https://www.cnblogs.com/ShoneSharp. 摘要: ...
- wordpress中文章发布时间不显示?用get_the_date代替the_date
今天发现,在主题中部分地方使用the_date函数来显示文章发布的时间时,竟然发生不显示时间的情况,再仔细看了一下这些文章,有些都是经过几次修改和保存的,可能是由于the_date只是显示文章第一次发 ...
- Docker入门 安装Tomcat以及报404解决方案
时间:2020/1/18 17:34:09 浏览:24 来源:互联网 记录简单的在Docker 上安装Tomcat 首先我是在云服务器上(Centos系统)安装的Docker,我们需要在https:/ ...
- npm audit fix 报错
found 2504 vulnerabilities (1360 low, 1109 moderate, 29 high, 6 critical) run `npm audit fix` to fi ...
- UIAutomator2的API文档(一)
检查并维持设备端守护进程处于运行状态,应该是重启了atx守护进程:d.healthcheck() 1.隐式等待 import uiautomator2 as u2serialno = '7f3dec6 ...