精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

求你了,不要再在對外接口中使用枚舉類型了!

開發 開發工具
我只是不建議在對外提供的接口的出入參中使用枚舉,并不是說徹底不要用枚舉,我之前很多文章也提到過,枚舉有很多好處,我在代碼中也經常使用。所以,切不可因噎廢食。

[[354980]]

最近,我們的線上環境出現了一個問題,線上代碼在執行過程中拋出了一個IllegalArgumentException,分析堆棧后,發現最根本的的異常是以下內容:

  1. java.lang.IllegalArgumentException:  
  2.  
  3. No enum constant com.a.b.f.m.a.c.AType.P_M 

大概就是以上的內容,看起來還是很簡單的,提示的錯誤信息就是在AType這個枚舉類中沒有找到P_M這個枚舉項。

于是經過排查,我們發現,在線上開始有這個異常之前,該應用依賴的一個下游系統有發布,而發布過程中是一個API包發生了變化,主要變化內容是在一個RPC接口的Response返回值類中的一個枚舉參數AType中增加了P_M這個枚舉項。

但是下游系統發布時,并未通知到我們負責的這個系統進行升級,所以就報錯了。

我們來分析下為什么會發生這樣的情況。

問題重現

首先,下游系統A提供了一個二方庫的某一個接口的返回值中有一個參數類型是枚舉類型。

一方庫指的是本項目中的依賴

二方庫指的是公司內部其他項目提供的依賴

三方庫指的是其他組織、公司等來自第三方的依賴

  1. public interface AFacadeService { 
  2.  
  3.     public AResponse doSth(ARequest aRequest); 
  4.  
  5.  
  6. public Class AResponse{ 
  7.  
  8.     private Boolean success; 
  9.  
  10.     private AType aType; 
  11.  
  12.  
  13. public enum AType{ 
  14.  
  15.     P_T, 
  16.  
  17.     A_B 
  18.  

然后B系統依賴了這個二方庫,并且會通過RPC遠程調用的方式調用AFacadeService的doSth方法。

  1. public class BService { 
  2.  
  3.     @Autowired 
  4.  
  5.     AFacadeService aFacadeService; 
  6.  
  7.     public void doSth(){ 
  8.  
  9.         ARequest aRequest = new ARequest(); 
  10.  
  11.         AResponse aResponse = aFacadeService.doSth(aRequest); 
  12.  
  13.         AType aType = aResponse.getAType(); 
  14.  
  15.     } 
  16.  

這時候,如果A和B系統依賴的都是同一個二方庫的話,兩者使用到的枚舉AType會是同一個類,里面的枚舉項也都是一致的,這種情況不會有什么問題。

但是,如果有一天,這個二方庫做了升級,在AType這個枚舉類中增加了一個新的枚舉項P_M,這時候只有系統A做了升級,但是系統B并沒有做升級。

那么A系統依賴的的AType就是這樣的:

  1. public enum AType{ 
  2.  
  3.     P_T, 
  4.  
  5.     A_B, 
  6.  
  7.     P_M 
  8.  

而B系統依賴的AType則是這樣的:

  1. public enum AType{ 
  2.  
  3.     P_T, 
  4.  
  5.     A_B 
  6.  

這種情況下,在B系統通過RPC調用A系統的時候,如果A系統返回的AResponse中的aType的類型為新增的P_M時候,B系統就會無法解析。一般在這種時候,RPC框架就會發生反序列化異常。導致程序被中斷。

原理分析

這個問題的現象我們分析清楚了,那么再來看下原理是怎樣的,為什么出現這樣的異常呢。

其實這個原理也不難,這類RPC框架大多數會采用JSON的格式進行數據傳輸,也就是客戶端會將返回值序列化成JSON字符串,而服務端會再將JSON字符串反序列化成一個Java對象。

而JSON在反序列化的過程中,對于一個枚舉類型,會嘗試調用對應的枚舉類的valueOf方法來獲取到對應的枚舉。

而我們查看枚舉類的valueOf方法的實現時,就可以發現,如果從枚舉類中找不到對應的枚舉項的時候,就會拋出IllegalArgumentException:

  1. public static <T extends Enum<T>> T valueOf(Class<T> enumType, String name) { 
  2.  
  3.     T result = enumType.enumConstantDirectory().get(name); 
  4.  
  5.     if (result != null
  6.  
  7.         return result; 
  8.  
  9.     if (name == null
  10.  
  11.         throw new NullPointerException("Name is null"); 
  12.  
  13.     throw new IllegalArgumentException( 
  14.  
  15.         "No enum constant " + enumType.getCanonicalName() + "." + name); 
  16.  

關于這個問題,其實在《阿里巴巴Java開發手冊》中也有類似的約定:

這里面規定"對于二方庫的參數可以使用枚舉,但是返回值不允許使用枚舉"。這背后的思考就是本文上面提到的內容。

擴展思考

為什么參數中可以有枚舉?

不知道大家有沒有想過這個問題,其實這個就和二方庫的職責有點關系了。

一般情況下,A系統想要提供一個遠程接口給別人調用的時候,就會定義一個二方庫,告訴其調用方如何構造參數,調用哪個接口。

而這個二方庫的調用方會根據其中定義的內容來進行調用。而參數的構造過程是由B系統完成的,如果B系統使用到的是一個舊的二方庫,使用到的枚舉自然是已有的一些,新增的就不會被用到,所以這樣也不會出現問題。

比如前面的例子,B系統在調用A系統的時候,構造參數的時候使用到AType的時候就只有P_T和A_B兩個選項,雖然A系統已經支持P_M了,但是B系統并沒有使用到。

如果B系統想要使用P_M,那么就需要對該二方庫進行升級。

但是,返回值就不一樣了,返回值并不受客戶端控制,服務端返回什么內容是根據他自己依賴的二方庫決定的。

但是,其實相比較于手冊中的規定,我更加傾向于,在RPC的接口中入參和出參都不要使用枚舉。

一般,我們要使用枚舉都是有幾個考慮:

  • 1、枚舉嚴格控制下游系統的傳入內容,避免非法字符。
  • 2、方便下游系統知道都可以傳哪些值,不容易出錯。

不可否認,使用枚舉確實有一些好處,但是我不建議使用主要有以下原因:

  • 1、如果二方庫升級,并且刪除了一個枚舉中的部分枚舉項,那么入參中使用枚舉也會出現問題,調用方將無法識別該枚舉項。
  • 2、有的時候,上下游系統有多個,如C系統通過B系統間接調用A系統,A系統的參數是由C系統傳過來的,B系統只是做了一個參數的轉換與組裝。這種情況下,一旦A系統的二方庫升級,那么B和C都要同時升級,任何一個不升級都將無法兼容。

我其實建議大家在接口中使用字符串代替枚舉,相比較于枚舉這種強類型,字符串算是一種弱類型。

如果使用字符串代替RPC接口中的枚舉,那么就可以避免上面我們提到的兩個問題,上游系統只需要傳遞字符串就行了,而具體的值的合法性,只需要在A系統內自己進行校驗就可以了。

為了方便調用者使用,可以使用javadoc的@see注解表明這個字符串字段的取值從那個枚舉中獲取。

  1. public Class AResponse{ 
  2.  
  3.     private Boolean success; 
  4.  
  5.     /** 
  6.  
  7.     *  @see AType  
  8.  
  9.     */ 
  10.  
  11.     private String aType; 
  12.  

對于像阿里這種比較龐大的互聯網公司,隨便提供出去的一個接口,可能有上百個調用方,而接口升級也是常態,我們根本做不到每次二方庫升級之后要求所有調用者跟著一起升級,這是完全不現實的,并且對于有些調用者來說,他用不到新特性,完全沒必要做升級。

還有一種看起來比較特殊,但是實際上比較常見的情況,就是有的時候一個接口的聲明在A包中,而一些枚舉常量定義在B包中,比較常見的就是阿里的交易相關的信息,訂單分很多層次,每次引入一個包的同時都需要引入幾十個包。

對于調用者來說,我肯定是不希望我的系統引入太多的依賴的,一方面依賴多了會導致應用的編譯過程很慢,并且很容易出現依賴沖突問題。

所以,在調用下游接口的時候,如果參數中字段的類型是枚舉的話,那我沒辦法,必須得依賴他的二方庫。但是如果不是枚舉,只是一個字符串,那我就可以選擇不依賴。

所以,我們在定義接口的時候,會盡量避免使用枚舉這種強類型。規范中規定在返回值中不允許使用,而我自己要求更高,就是即使在接口的入參中我也很少使用。

最后,我只是不建議在對外提供的接口的出入參中使用枚舉,并不是說徹底不要用枚舉,我之前很多文章也提到過,枚舉有很多好處,我在代碼中也經常使用。所以,切不可因噎廢食。

當然,文中的觀點僅代表我個人,具體是是不是適用其他人,其他場景或者其他公司的實踐,需要讀者們自行分辨下,建議大家在使用的時候可以多思考一下。

【本文是51CTO專欄作者Hollis的原創文章,作者微信公眾號Hollis(ID:hollischuang)】 

戳這里,看該作者更多好文

 

責任編輯:武曉燕 來源: 51CTO專欄
相關推薦

2017-07-03 15:04:41

2020-09-22 09:05:45

MySQLUTF-8utf8mb4

2021-09-30 06:13:36

打印日志error

2020-04-07 08:34:00

===開發語言

2020-12-04 10:05:00

Pythonprint代碼

2020-12-02 11:18:50

print調試代碼Python

2020-05-09 10:18:31

Java開源工具

2020-06-15 08:12:51

try catch代碼處理器

2021-05-11 07:10:18

標準庫DjangoOS

2023-09-27 10:19:37

類型video函數

2020-12-11 09:24:19

Elasticsear存儲數據

2020-10-12 10:45:44

nullava程序員

2024-03-06 08:36:36

2019-11-20 23:44:29

接口數據加密數據安全

2024-06-12 13:54:37

編程語言字符串代碼

2020-12-15 08:06:45

waitnotifyCondition

2025-02-10 08:05:03

2020-06-23 14:52:04

Python無用分號語言

2020-04-16 08:22:11

HTTPS加解密協議

2025-08-18 09:35:02

點贊
收藏

51CTO技術棧公眾號

337p亚洲精品色噜噜噜| 久久久夜色精品亚洲| 久久久精品亚洲| 国产人妻精品午夜福利免费| 97久久人人超碰caoprom| 91网站最新网址| 国产精品一区二区性色av| 午夜69成人做爰视频| 思热99re视热频这里只精品| 欧美无砖砖区免费| 99久久免费观看| 欧美欧美欧美| 国产精品一区二区久激情瑜伽| 久久91精品国产91久久久| 亚洲AV无码国产精品| 中文字幕成人| 色视频成人在线观看免| 欧洲金发美女大战黑人| 美女做暖暖视频免费在线观看全部网址91 | 亚洲激情国产精品| 美女黄色片视频| 男人添女人下部高潮视频在线观看 | 欧美三区在线| 国产亚洲精品美女| 免费不卡的av| 欧美二区观看| 欧美伊人精品成人久久综合97| 国产天堂视频在线观看| 午夜老司机在线观看| 91香蕉视频mp4| 高清视频一区二区三区| 中文字幕欧美人妻精品一区蜜臀| 亚洲激情黄色| 欧美日韩国产成人在线| 99久久99久久精品免费| 亚洲人和日本人hd| 亚洲国产精品人久久电影| 国产aⅴ爽av久久久久| 欧美xxx性| 亚洲成人黄色影院| 欧美日韩午夜爽爽| 黄网页免费在线观看| 国产亚洲一区二区三区在线观看| 国语精品免费视频| 黄频网站在线观看| 国产精品亚洲第一| 91久久精品美女高潮| 91在线精品入口| 青青草国产成人av片免费| 人人爽久久涩噜噜噜网站| 国产系列精品av| 欧美精品偷拍| 久久久久久12| 国产真实乱人偷精品视频| 中文字幕一区二区av| 久久精品亚洲国产| 日韩欧美123区| 久久久久午夜电影| 久久亚洲精品中文字幕冲田杏梨 | 欧洲grand老妇人| 亚洲精品自在久久| 亚洲欧美视频在线播放| 琪琪久久久久日韩精品| 亚洲精品一区久久久久久| 亚洲精品视频大全| 国产一区二区三区四区五区| 亚洲丝袜一区在线| 欧美成人另类视频| 99欧美视频| 色综合91久久精品中文字幕| 精品处破女学生| 国产欧美丝祙| 国产精品成人播放| 国产精品一区二区黑人巨大| 精品综合免费视频观看| 91久久偷偷做嫩草影院| 亚洲国产av一区二区| av一区二区三区在线| 免费国产在线精品一区二区三区| 国产在线你懂得| 国产精品三级久久久久三级| 欧美亚洲视频一区| 国产在线xxx| 色婷婷久久久久swag精品| 免费涩涩18网站入口| 精品一区二区三区四区五区| 亚洲激情免费观看| 国产又粗又长又硬| 亚洲欧美色图| 日本三级韩国三级久久| 亚洲最大成人av| 成人精品免费视频| 天堂一区二区三区| 人妖欧美1区| 在线免费观看视频一区| 亚洲在线观看网站| 亚洲免费观看高清完整版在线观| 日韩一区av在线| 国产精品第72页| 蜜臀av在线播放一区二区三区| 91久色国产| 国产裸舞福利在线视频合集| 亚洲综合色噜噜狠狠| 成人在线观看a| jizz国产精品| 最近中文字幕日韩精品 | 91网免费观看| 免费黄色片在线观看| 亚洲精品国产精华液| 精品国产成人av在线免| 亚洲精品在线播放| 亚洲性xxxx| 国产成人一区二区三区影院在线| 看片的网站亚洲| 美女一区视频| 国产在线拍揄自揄拍视频| 欧美日韩国产一区| 波多野结衣一本| 亚洲网站在线| 91在线免费看网站| av在线收看| 色综合视频在线观看| 中文字幕1区2区| 日韩aaaa| 国产精品青青在线观看爽香蕉| 香蕉视频免费看| 一区二区三区国产豹纹内裤在线| 中文字幕永久有效| jizzjizz欧美69巨大| 欧美亚洲日本黄色| 色婷婷视频在线| 亚洲一区二区美女| 香蕉视频色在线观看| 久久综合av| 国产精品av网站| 精品成人一区二区三区免费视频| 五月天精品一区二区三区| 中国男女全黄大片| 欧美欧美天天天天操| 成人h猎奇视频网站| 成人在线免费看| 日本高清不卡aⅴ免费网站| 好吊日免费视频| 99精品国产一区二区青青牛奶| 国产v亚洲v天堂无码| 成人高清免费在线| 日韩一区二区在线免费观看| 五月综合色婷婷| 国内精品伊人久久久久av影院 | 久久精品ww人人做人人爽| 97人人爽人人澡人人精品| 精品国产乱码久久久久久久久| 黄色一级视频免费观看| 国产精品一区一区| 国产精品久久久久9999爆乳| 成人福利免费在线观看| 韩剧1988免费观看全集| 无码精品在线观看| 日韩欧美国产网站| 91久久免费视频| 日本少妇一区二区| 综合色婷婷一区二区亚洲欧美国产| 少妇高潮一区二区三区99| 久久久99久久精品女同性| 国产女人爽到高潮a毛片| 一区二区三区高清不卡| 精品无码国产一区二区三区51安| 香蕉精品999视频一区二区| 欧美日韩一区二区视频在线观看 | x88av在线| 久久99精品久久久久久久久久久久 | 国产精品视频最多的网站| 九色porny在线| 亚洲成人xxx| 波多野结衣电车痴汉| 中文字幕日韩av资源站| 欧美一级片在线免费观看| 亚洲日本欧美| 四虎永久在线精品免费一区二区| 超碰国产精品一区二页| 欧美—级a级欧美特级ar全黄| 视频午夜在线| 色av成人天堂桃色av| 国产免费一区二区三区四区| 粉嫩aⅴ一区二区三区四区五区| 欧美网站免费观看| 日韩国产一区二区| 国产精品12| 成人涩涩视频| 久久久免费精品| 国产露出视频在线观看| 日韩午夜在线播放| 无码人妻丰满熟妇精品区| 最新国产の精品合集bt伙计| 中文字幕免费高清视频| 免费在线视频一区| 国产玉足脚交久久欧美| 不卡在线一区| 国产精品免费在线播放| 成人国产一区| 欧美中文在线免费| 性直播体位视频在线观看| 亚洲人午夜精品| 丰满人妻一区二区| 欧美性猛交xxxx乱大交退制版| 久青草视频在线观看| 中文字幕精品综合| 天天插天天射天天干| 极品尤物av久久免费看| 男人揉女人奶房视频60分 | 狠狠爱免费视频| 欧美一区影院| 亚洲精品9999| 宅男在线一区| 国内成+人亚洲| 日韩精品成人在线观看| 国产精品视频白浆免费视频| 欧美少妇精品| 欧美激情一级精品国产| 黄色网页在线免费看| 一本色道久久88综合日韩精品| 四虎精品一区二区三区| 日韩一区国产二区欧美三区| 一区二区三区免费观看视频| 欧美性xxxxhd| 日韩av在线天堂| 洋洋成人永久网站入口| 99鲁鲁精品一区二区三区| 欧美国产97人人爽人人喊| 国精产品一区一区三区免费视频| 成人免费av资源| 韩国三级hd中文字幕有哪些| 激情综合色丁香一区二区| 亚洲免费av一区二区三区| 国产九九精品| 男人天堂999| 久久国产精品久久w女人spa| 奇米影视亚洲色图| 狠狠干综合网| 欧美一级爱爱视频| 欧美精品97| avav在线播放| 欧美午夜电影在线观看 | 精品午夜一区二区| 牛牛影视一区二区三区免费看| 国产精品久久久久久久天堂第1集| 国产午夜久久av| 国产日本欧美一区二区三区在线| 成人mm视频在线观看| 国产精品精品视频| 国产经典一区| 国产玖玖精品视频| 日日夜夜精品| 91麻豆国产精品| 国产一区二区三区亚洲综合| 91高跟黑色丝袜呻吟在线观看| 国产一区二区三区免费在线| 不卡一区二区三区视频| **爰片久久毛片| 国产一区二区三区四区五区在线 | 久久久久久久久久久影院| 欧美性xxxxxxxxx| 亚洲高清在线看| 欧美日韩精品欧美日韩精品一 | 美国十次综合久久| julia一区二区中文久久94| 都市激情亚洲| 久久久久久久久一区| 国产aⅴ精品一区二区三区久久| 日本不卡二区高清三区| 久久国产影院| 成人国产一区二区三区| 日韩午夜免费视频| 日韩精品无码一区二区三区免费| 久久狠狠亚洲综合| 风韵丰满熟妇啪啪区老熟熟女| 91日韩精品一区| 国产传媒视频在线| 亚洲影院理伦片| 国产一级一级国产| 91精品麻豆日日躁夜夜躁| 亚洲 欧美 自拍偷拍| 在线播放国产精品| 怡红院在线观看| 日韩av片免费在线观看| 欧美一级免费| 久久久影院一区二区三区| 欧美好骚综合网| 日韩欧美国产综合在线| 美女国产一区二区| 日韩无码精品一区二区| 日本一区二区久久| 久久久久无码精品国产| 在线看国产日韩| 男人天堂一区二区| 最近更新的2019中文字幕 | 成人免费在线视频网址| 久久精品色综合| 香蕉精品视频在线| 噜噜爱69成人精品| 国产麻豆剧传媒精品国产| 久久亚洲综合av| 久久久久成人网站| 精品视频在线免费| 色网站在线免费观看| 超碰91人人草人人干| 国产精品亚洲一区二区三区在线观看| 亚洲自拍偷拍色片视频| 亚洲精品蜜桃乱晃| 国产91视频一区| 久久99日本精品| 欧美黑人欧美精品刺激| 一区二区三区在线免费视频| 国产免费a视频| 国产视频亚洲视频| 超免费在线视频| 666精品在线| 国产精品99一区二区三| 成年人视频网站免费观看| 国产伦精品一区二区三区免费迷| 天堂在线中文视频| 日韩欧美a级成人黄色| 亚洲老妇色熟女老太| 久久人人爽人人爽爽久久| 亚洲爱爱视频| 日本不卡一区| 久久夜色精品| 欧美熟妇精品黑人巨大一二三区| 亚洲国产精品影院| 亚洲国产精彩视频| 成人97在线观看视频| 国产视频一区二| 一级全黄肉体裸体全过程| 蜜臀av性久久久久av蜜臀妖精| 免费污网站在线观看| 色综合久久中文字幕| 日韩大胆人体| 日韩av电影在线播放| 亚洲瘦老头同性70tv| av片中文字幕| 国产亚洲欧美一区在线观看| 波多野结衣大片| 中文字幕日韩av| 欧美aaaaaaaa| 欧美aaa在线观看| 韩国av一区二区三区在线观看| 人妻无码一区二区三区免费| 欧美午夜精品久久久久久孕妇| av小片在线| 国产拍精品一二三| 精品av一区二区| 久久精品影视大全| 国产精品久久久久久久岛一牛影视 | 亚洲美女黄色| 99久久人妻无码中文字幕系列| 午夜伦理一区二区| 手机福利小视频在线播放| 国产成人精品久久久| 三上亚洲一区二区| 亚洲精品视频三区| 一区二区欧美视频| 少妇av在线播放| 日韩免费av在线| 久久亚洲成人| 久久久久久无码精品人妻一区二区| 亚洲一区视频在线| 日av在线播放| 国产日韩欧美日韩大片| 欧美在线首页| 精品无码在线视频| 欧美三片在线视频观看| 在线观看中文字幕的网站| 国产精品视频一区二区三区经| 亚洲精品激情| 成人无码av片在线观看| 欧美一区二区在线视频| 精品极品在线| 亚洲人成网站在线播放2019| 国产一区二区不卡在线| 日韩乱码一区二区| 在线观看欧美www| 97久久综合精品久久久综合| 日韩久久一级片| 亚洲免费高清视频在线| 五月婷婷六月丁香综合| 国产精品视频99| 亚洲大胆在线| 黄色av片三级三级三级免费看| 日韩天堂在线观看| 日韩福利一区| 99久久99久久精品| 国产校园另类小说区| 亚洲av无码国产精品久久不卡 | 中国老头性行为xxxx| 久久91亚洲精品中文字幕| 国产欧美日韩精品一区二区免费 | 2019中文在线观看| 999精品一区| av小说在线观看| 日韩欧美国产不卡|