当前位置:网站首页>Please, don't use enumeration types in external interfaces any more!
Please, don't use enumeration types in external interfaces any more!
2022-06-11 13:25:00 【Java technology stack】
Click on the official account ,Java dried food Timely delivery 
lately , There's a problem with our online environment , The online code throws a IllegalArgumentException, After analyzing the stack , The most fundamental anomaly found is the following :
java.lang.IllegalArgumentException:
No enum constant com.a.b.f.m.a.c.AType.P_MIt's about the above , It seems very simple , The error message is in AType This enumeration class did not find P_M This enumeration .
So after investigation , We found that , Before this anomaly began to appear online , The application relies on a downstream system that has a release , And the release process is a API The bag has changed , The main change is in a RPC Interface Response An enumeration parameter in the return value class AType Added in P_M This enumeration .
But when the downstream system is released , We were not informed of the upgrade of the system we were responsible for , So I made a mistake .
Let's analyze why this happens .
Problem recurrence
First , Downstream system A The return value of an interface that provides a binary library has an enumeration type .
One party library refers to the dependencies in this project
Two party library refers to the dependencies provided by other projects within the company
The tripartite library refers to other organizations 、 Companies, etc. rely on third parties
public interface AFacadeService {
public AResponse doSth(ARequest aRequest);
}
public Class AResponse{
private Boolean success;
private AType aType;
}
public enum AType{
P_T,
A_B
} then B The system relies on this binary Library , And will pass RPC Call in the way of remote call AFacadeService Of doSth Method .
public class BService {
@Autowired
AFacadeService aFacadeService;
public void doSth(){
ARequest aRequest = new ARequest();
AResponse aResponse = aFacadeService.doSth(aRequest);
AType aType = aResponse.getAType();
}
}Now , If A and B If the system depends on the same binary Library , Enumerations used for both AType It's going to be the same class , The enumerations are consistent , There's no problem with this situation .
however , If one day , This binary library has been upgraded , stay AType A new enumeration item is added to this enumeration class P_M, It's just the system A Made an upgrade , But the system B No upgrade .
that A System dependent AType That's it :
public enum AType{
P_T,
A_B,
P_M
}and B System dependent AType It looks like this :
public enum AType{
P_T,
A_B
}In this case , stay B The system goes through RPC call A System time , If A The system returned AResponse Medium aType The type of is new P_M When ,B The system will not be able to parse . Usually at this time ,RPC The framework will have a deserialization exception . Cause the program to be interrupted .
Principle analysis
We have analyzed the phenomenon of this problem clearly , So let's take a look at the principle , Why is this abnormal .
In fact, this principle is not difficult , This kind of RPC Most frameworks use JSON Data transmission format , In other words, the client will sequence the return value into JSON character string , And the server will again JSON Deserialize a string into a Java object .
and JSON In the process of deserialization , For an enumeration type , Will try to call the corresponding enumeration class valueOf Method to get the corresponding enumeration .
And let's look at the enumeration class valueOf Method implementation , You can find , If you can't find the corresponding enumeration item from the enumeration class , Will throw IllegalArgumentException:
public static <T extends Enum<T>> T valueOf(Class<T> enumType, String name) {
T result = enumType.enumConstantDirectory().get(name);
if (result != null)
return result;
if (name == null)
throw new NullPointerException("Name is null");
throw new IllegalArgumentException(
"No enum constant " + enumType.getCanonicalName() + "." + name);
}On this question , Actually in 《 Alibaba Java Development Manual 》 There is a similar agreement in :

It says " For binary library parameters, you can use enumeration , But enumerations are not allowed for return values ". The thinking behind this is the content mentioned above in this paper .
Expand the thinking
Why can there be enumerations in parameters ?
I don't know if you've thought about it , In fact, this has something to do with the responsibilities of the second party library .
In general ,A When the system wants to provide a remote interface for others to call , It defines a binary Library , Tell its callers how to construct parameters , Which interface to call .
The callers of this two-party library will call according to the content defined in it . And the construction of parameters is done by B The system completes , If B The system uses an old binary Library , The enumerations used are naturally some existing ones , The new ones won't be used , So it won't be a problem .
For example, the previous example ,B The system is calling A System time , When we construct parameters, we use AType When it comes to P_T and A_B Two options , although A The system already supports P_M 了 , however B The system doesn't use .
If B The system wants to use P_M, Then we need to upgrade the library .
however , The return value is different , The return value is not controlled by the client , What content the server returns is determined by the binary library it relies on .
however , In fact, compared with the provisions in the manual , I'm more inclined to , stay RPC Do not use enumerations for both input and output parameters .
commonly , There are several considerations when we want to use enumeration :
1、 Enumeration strictly controls the incoming content of downstream system , Avoid illegal characters .
2、 It is convenient for the downstream system to know what values can be transferred , Not easy to make mistakes .
Undeniable? , There are some benefits to using enumerations , But I don't recommend it for the following reasons :
1、 If the binary library is upgraded , And delete some enumeration items in an enumeration , Then there will be problems with enumerations in input parameters , The enumerator will not be recognized by the caller .
2、 sometimes , There are many upstream and downstream systems , Such as C The system goes through B The system indirectly calls A System ,A The parameters of the system are determined by C From the system ,B The system just does a parameter conversion and assembly . In this case , once A Upgrade the binary Library of the system , that B and C All have to be upgraded at the same time , Any one that doesn't upgrade will not be compatible .
I actually suggest that you use strings instead of enumerations in interfaces , Compared to enumeration, this strong type , String is a weak type .
If you use a string instead of RPC Enumeration in interface , Then we can avoid the two problems mentioned above , The upstream system just needs to pass a string , And the legitimacy of specific values , Only need A It's OK to check the system itself .
For the convenience of the caller , have access to javadoc Of @see The annotation indicates that the value of the string field is taken from that enumeration .
public Class AResponse{
private Boolean success;
/**
* @see AType
*/
private String aType;
}For a relatively large Internet company like Ali , Just provide an interface to go out , There could be hundreds of callers , And interface upgrade is normal , We can't ask all callers to upgrade after every upgrade of the binary library , It's totally unrealistic , And for some callers , He doesn't use the new features , There's no need to upgrade .
There's another one that looks special , But it's actually quite common , That is, sometimes an interface declaration is in A In bag , Some enumeration constants are defined in B In bag , More common is the transaction related information of Ali , There are many levels of orders , Each time a package is introduced, dozens of packages need to be introduced .
For the caller , I certainly don't want my system to introduce too many dependencies , On the one hand, too much dependency will lead to the slow compilation process of the application , And it's easy to have dependency conflicts .
therefore , When calling the downstream interface , If the type of the field in the parameter is enumeration , I can't help it , We have to rely on his library . But if it's not enumeration , Just a string , Then I can choose not to rely on .
therefore , When we define interfaces , We try to avoid using strong types like enumerations . The specification states that it is not allowed to use... In the return value , And I'm more demanding myself , Even in the input parameters of the interface, I seldom use .
Last , I just don't recommend enumerations in the input and output parameters of the interface provided externally , That's not to say don't use enumerations at all , Many of my previous articles have also mentioned , Enumeration has many advantages , I also use it a lot in my code . therefore , Never stop eating because of choking .
Of course , The point of view in this article only represents me , Is it applicable to other people , Other scenarios or practices of other companies , It's up to the reader to distinguish , I suggest that you can think more about it when you use it .

Last
It took six years ,“Java The way for engineers to become gods ” The series finally published its first paper book 《 In depth understanding of Java The core technology : written Java Engineer's dry goods notes ( The basic chapter )》 The paper version has been rewritten “ The basic chapter ” among 80% The content of . The overall structure is more reasonable than the open source version , The content is also richer than the open source version . The book introduces the common Java Related knowledge that engineers must learn , Including object-oriented and Java The foundation of language consists of two parts , Covers basic data types 、 keyword 、 abnormal 、I/O flow 、 aggregate 、 Reflection 、 Generics and enumerations ...... In addition, there is a “ Oh my god ” Colored eggs , Let you call magic .

Who is this book for
The following groups of people Not suitable for Read this book :
1、 Someone who has no programming experience at all ; This book is not cook book, I can't help you 21 Sky master Java, No virtual machine installed from 、 To configure classpath Speak up .
2、 Just think the code can run when it's written , Resist everything " eight-part essay ( a literary composition prescribed for the imperial civil service examinations, knows for it rigidity of form and poverty of ideas ) " People who ; Many of the knowledge points in this book come from working " pit "、 The book analyzes a lot of source code , It's a book that goes deep into principles . A complete " eight-part essay ( a literary composition prescribed for the imperial civil service examinations, knows for it rigidity of form and poverty of ideas ) " Treasure .
others , Whether it's a novice who has just worked for a year or two , Or an old driver who has worked for five or six years ; Whether you are preparing to find a job, you need an interview Dictionary , You still need a book to help you avoid the pits at work ; Whether it is systematic learning as a knowledge system , Or daily learning as a way to check deficiencies and fill gaps .
This book , All for you .
in addition ,618 Promoting welfare , The original price of this book is 138, Now go in and get one 618 Coupons , The discount price is 87, If you need this book, you can also place an order directly .
Free books
Here comes the chance to get the book for free , Free now 、 Package delivery 5 Ben 《 In depth understanding of Java The core technology : written Java Engineer's dry goods notes ( The basic chapter )》 Books , Welcome to leave a message about your understanding of enumeration , I will choose in a few days 5 Selected messages sent out .
边栏推荐
- 长连接简介
- Why does each running Department display that the database already exists, delete the database, and then succeed? Each running department must delete the database, and re run the whole successfully
- ecplise无法连接sql server
- [bug resolution] the form is paged to display the total data res.data total
- SAP Spartacus checkout 流程使用 url 粘贴直接跳转到 delivery mode不能打开页面的原因
- 添加环境路径
- Hashicopy之nomad应用编排方案08(检测Job)
- 利用 VSCode 的代码模板提高 MobX 的编码效率
- From quic to TCP
- kubernetes 证书合集
猜你喜欢

【信号处理】数字信号处理Matlab设计附GUI界面和报告

面试造航母,入职拧螺丝,工资...

Using vscode code code template to improve mobx coding efficiency

【滤波器】基于matlab时变维纳滤波器设计【含Matlab源码 1870期】

Network information system emergency response

Business practice of volcano engine cloud database VEDB in bytes

JSP实现银柜台业务绩效考核系统

JDBC连接池去做批量导入,每次运行500万数据,但是在中间就会出各种问题

How about NFT market? Why is NFT so popular? How to build NFT platform

Will Apple build a search engine?
随机推荐
Business practice of volcano engine cloud database VEDB in bytes
看不懂Kotlin源码?从Contracts 函数说起~
Nomad application scheduling scheme 08 of hashicopy (detection job)
Development of smart contract DAPP system for TRX wave field chain
[bug resolution] after uploading the image, cancel the upload and upload again. The last image still exists
如何写出高性能代码(四)优化数据访问
Energy storage operation and configuration analysis of high proportion wind power system (realized by Matlab)
Clear the selected data in the modal box after the modal box is closed
kubernetes 证书合集
Add function drop-down multiple selections to display the selected personnel
Unity detects whether the object is within the viewing cone of the camera
Introduction to common fonts
火山引擎云数据库 veDB 在字节内部的业务实践
AGV机器人RFID传感器CK-G06A与西门子1200PLC应用手册
不谈赛道,不聊风口,开源数据库巨头Cassandra如何在国内讲好“新故事” | C位面对面
Can't understand kotlin source code? Starting with the contracts function~
Microsoft exposes another "scandal": watching VR porn in the office, "the father of hololens" is about to leave!
On software defects and loopholes
Explain in detail the differences between real participation formal parameters in C language
SAP Spartacus checkout process uses URL paste to directly jump to delivery mode. Why the page cannot be opened