《Java開發手冊》泰山版來襲!

Java開發手冊-泰山版

會當凌絕頂,一覽衆山小

終於迎來了《Java開發手冊》的一個新的版本——泰山版。

新版本說明

此次泰山版發佈,將帶來三大亮點:新增5條日期時間規約;新增2條表別名sql規約;新增統一錯誤碼規約。

Java開發手冊-泰山版改動

5條日期時間規約

  • 【強制】日期格式化時,傳入pattern中表示年份統一使用小寫的y。

    說明:日期格式化時,yyyy表示當天所在的年,而大寫的YYYY代表是week in which year(JDK7之後引入的概念),意思是當天所在的周屬於的年份,一週從週日開始,週六結束,只要本週跨年,返回的YYYY就是下一年。

    正例:表示日期和時間的格式如下所示:

      	new SimpleDateFormat("yyyy-MM-dd HH:mm:ss") 
    
  • 【強制】在日期格式中分清楚大寫的M和小寫的m,大寫的H和小寫的h分別指代的意義。

    說明:日期格式中的這兩對字母表意如下:

    1) 表示月份是大寫的M;

    2) 表示分鐘則是小寫的m;

    3) 24小時制的是大寫的H;

    4) 12小時制的則是小寫的h。

  • 【強制】獲取當前毫秒數:System.currentTimeMillis(); 而不是new Date().getTime()。

    說明:如果想獲取更加精確的納秒級時間值,使用System.nanoTime的方式。在JDK8中,針對統計時間等場景,推薦使用Instant類。

  • 【強制】不允許在程序任何地方中使用:1)java.sql.Date 2)java.sql.Time 3)java.sql.Timestamp。

    說明:第1個不記錄時間,getHours()拋出異常;第2個不記錄日期,getYear()拋出異常;第3個在構造方法super((time/1000)*1000),fastTime和nanos分開存儲秒和納秒信息。

    反例: java.util.Date.after(Date)進行時間比較時,當入參是java.sql.Timestamp時,會觸發JDK BUG(JDK9已修復),可能導致比較時的意外結果。

  • 【強制】不要在程序中寫死一年爲365天,避免在公曆閏年時出現日期轉換錯誤或程序邏輯錯誤。

    正例

    // 獲取今年的天數 
    int daysOfThisYear = LocalDate.now().lengthOfYear();
    
    // 獲取指定某年的天數
    LocalDate.of(2011, 1, 1).lengthOfYear(); 
    

    反例

    // 第一種情況:在閏年366天時,出現數組越界異常 
    int[] dayArray = new int[365]; 
    
    // 第二種情況:一年有效期的會員制,今年1月26日註冊,硬編碼365返回的卻是1月25日 
    Calendar calendar = Calendar.getInstance(); calendar.set(2020, 1, 26); 
    calendar.add(Calendar.DATE, 365);  
    
  • 【推薦】避免公曆閏年2月問題。閏年的2月份有29天,一年後的那一天不可能是2月29日。

  • 【推薦】使用枚舉值來指代月份。如果使用數字,注意Date,Calendar等日期相關類的月份month取值在0-11之間。

    說明:參考JDK原生註釋,Month value is 0-based. e.g., 0 for January.

    正例: Calendar.JANUARY,Calendar.FEBRUARY,Calendar.MARCH等來指代相應月份來進行傳參或比較。

2條表別名sql規約

  • 【強制】對於數據庫中表記錄的查詢和變更,只要涉及多個表,都需要在列名前加表的別名(或表名)進行限定。

    說明:對多表進行查詢記錄、更新記錄、刪除記錄時,如果對操作列沒有限定表的別名(或表名),並且操作列在多個表中存在時,就會拋異常。

    正例:select t1.name from table_first as t1 , table_second as t2 where t1.id=t2.id;

    反例:在某業務中,由於多表關聯查詢語句沒有加表的別名(或表名)的限制,正常運行兩年後,最近在某個表中增加一個同名字段,在預發佈環境做數據庫變更後,線上查詢語句出現出1052異常:Column ‘name’ in field list is ambiguous。

  • 【推薦】SQL語句中表的別名前加as,並且以t1、t2、t3、…的順序依次命名。

    說明:1)別名可以是表的簡稱,或者是根據表出現的順序,以t1、t2、t3的方式命名。2)別名前加as使別名更容易識別。

    正例:select t1.name from table_first as t1, table_second as t2 where t1.id=t2.id;

三目運算符規範

  • 【強制】三目運算符condition? 表達式1 : 表達式2中,高度注意表達式1和2在類型對齊時,可能拋出因自動拆箱導致的NPE異常。

    說明:以下兩種場景會觸發類型對齊的拆箱操作:

    1) 表達式1或表達式2的值只要有一個是原始類型。

    2) 表達式1或表達式2的值的類型不一致,會強制拆箱升級成表示範圍更大的那個類型。

    反例

    Integer a = 1; 
    Integer b = 2; 
    Integer c = null; 
    Boolean flag = false; 
    // a*b的結果是int類型,那麼c會強制拆箱成int類型,拋出NPE異常 
    Integer result=(flag? a*b : c); 
    

新增統一錯誤碼規約

統一錯誤碼,就是統一度量衡,爲你的應用與服務的穩定保駕護航,煩惱清空,快樂回家。泰山版新近出爐的錯誤碼具有快速溯源、簡單易記、溝通標準化三大優勢。錯誤碼爲字符串類型,共 5 位,分成兩個部分:錯誤產生來源和四位數字編號。

錯誤產生來源分爲 A/B/C,以當前代碼運行視角來進行判定。

A 表示錯誤來源於用戶,比如請求參數錯誤,用戶安裝版本過低等問題;

B 表示錯誤來源於當前系統,往往是業務邏輯出錯,或程序健壯性差等問題;

C 表示錯誤來源於第三方服務,比如 CDN 服務出錯,消息投遞超時等問題。

優秀的錯誤碼可以迅速知道他們是怎麼來滴,從哪兒來滴,來幹啥滴。同時俺們的錯誤碼具有三級結構,分爲一級宏觀錯誤碼、二級宏觀錯誤碼、三級宏觀錯誤碼,這樣的方案更加可擴展,有彈性,更多詳細規則,見手冊的附件的《錯誤碼參考列表》。

Java開發手冊-A類錯誤碼

作者QA

作者孤盡也在QA視頻中回答了新增的幾條規約實際出現過的問題。

  • 在對JDK源碼閱讀技巧上給我們提了3點:

    1)一定要有發現美的眼睛;

    2)一定要有主線思維;

    3)不斷打磨自己的基礎,包括位運算、源碼調試,甚至可以看看JVM的C++源碼或者C++下的彙編代碼。

  • 你的Java開發規約在業界影響這麼大,你之前想到過有這一天嗎?

    作者表示沒有想到有這麼一天,從最初的的4、5個人的小團體走到阿里巴巴,最後發到業界去,他還是堅持初心,對大家有用有幫助,繼續傳播。

  • 是什麼支撐你每年推出新規約,我們知道這並不是你的本職工作。

    作者表示在於兩個詞,熱愛和卓越。但是要加上形容詞。「奉獻式的熱愛」和「極致式的卓越」

我們看到從去年的「華山版」開始,《Java開發手冊》就不再有阿里巴巴這樣的限定詞,作者的本意也是希望來致敬全球的開發者。因爲《Java開發手冊》發展到今天,已經不是單單屬於阿里巴巴或者孤盡個人,它屬於整個業界大家整體智慧的一個結晶。希望大家一起努力,將代碼演繹到極致,並寫出更優雅的代碼。

歷史版本

《Java開發手冊》一直在迭代,不知道下一個版本是什麼名字。

Java開發手冊-時間軸

一起學習

最後在阿里雲開發者社區裏,也特意給我們準備了7日訓練營的打卡挑戰,幫助大家更好的理解手冊,小夥伴們一起來參加吧還有可能獲得獎品。

Java開發手冊-打卡挑戰

相關資源地址

GitHub(包含IntelliJ IDEA和Eclipse的插件):alibaba/p3c: Alibaba Java Coding Guidelines

阿里雲開發者社區:泰山版Java開發手冊-阿里雲開發者社區


求關注、分享、在看!!! 你的支持是我創作最大的動力。

qrcode_mp

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章