為什麼阿裡巴巴Java開發手冊中強制要求介面返回值不允許使用枚舉?

来源:https://www.cnblogs.com/wupeixuan/archive/2020/06/06/13055919.html
-Advertisement-
Play Games

在閱讀《阿裡巴巴Java開發手冊》時,發現有一條關於二方庫依賴中介面返回值不允許使用枚舉類型的規約,具體內容如下: 在談論為什麼之前先來科普下什麼是二方庫,二方庫也稱作二方包,一般指公司內部發佈到中央倉庫,可供公司內部其他應用依賴的庫(jar 包)。 那麼一方庫便是本工程內部子項目模塊依賴的庫;三方 ...


在閱讀《阿裡巴巴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


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • import pandasexcel=pandas.read_excel('現代徵信學.xlsx',index_col='列名',header=None) #header預設為0,指讀取第幾行,0代表第一行excel.columns=['Id','title','hh','uei','t'] #重新 ...
  • Java生鮮電商平臺-生鮮小程式首頁系統功能詳解(小程式/APP) 說明:對於一個成熟的生鮮小程式而言,首頁至關重要,下麵我就列舉,我們系統中的首頁的功能,本文只是簡單的介紹下,以達到拋磚引玉的作用,希望對大家有點幫助。 QQ:137071249 共同學習QQ群:793305035 ...
  • 軟體開發的生命周期 既然我們以後從事的工作時軟體開發,那麼我們就要對軟體開發的流程先做瞭解,畢竟要從娃娃抓起。早點瞭解軟體開發流程,也就有了軟體開發的思想與動力。 軟體開發的生命周期 問題定義 問題定義 是軟體定義時期的第一個階段。作為軟體的開發者,在這個階段必須弄清用戶“需要電腦解決什麼問題”。 ...
  • import pandasa=pandas.DataFrame({'ID':[1,2,3],'Name':['Time','Mike','Nick']})b=a.set_index('ID') #重新設置索引b.to_excel(r'D:\電腦二級\ocr 訓練\a.xlsx') ...
  • 面完螞蟻後,早就聽聞拼多多這個獨角獸,決定也去面一把。首先我在脈脈找了一個拼多多的HR,加了微信聊了下,發了簡歷便開始我的拼多多面試之旅。這裡要非常感謝拼多多HR小姐姐,從面試內推到offer確認一直都在幫我,人真的很nice。 ...
  • from matplotlib import pyplotimport numpyx=numpy.random.randn(100) #生成100個隨機數,關於標準正態分佈 y=-x+numpy.random.randn(100)*0.5pyplot.scatter(x,y,s=25,c='pink ...
  • 所有知識體系文章,GitHub已收錄,歡迎Star!再次感謝,願你早日進入大廠! GitHub地址: https://github.com/Ziphtracks/JavaLearningmanual 01設計模式之單例設計模式 一、什麼是單例設計模式? 單例模式(Singleton Pattern) ...
  • 一、python的應用領域 二、人工智慧範例 1.範例1 將寫在紙上的文字,精準地識別出來 1 import requests 2 from aip import AipOcr 3 4 image = requests.get('https://res.pandateacher.com/python ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...