偶然看到阿里巴巴竟然出書了???趁着滿減活動(節約節約....)我趕忙買來準備看看,剛拿到的時候掂量了好多下,總以爲商家給我少發了一本書,結果打開才知道..原來這本書這麼小....html
別人都說咱們是搬磚的碼農,但咱們知道本身是追求個性的藝術家。也許咱們不會過多在乎本身的外表和穿着,但在咱們不羈的外表下,骨子裏追求着代碼的美、系統的美、設計的美,代碼規範其實就是一個對程序美的定義。—— 引自 序java
若是有一天在咱們的項目中看到了這樣的代碼:mysql
或者是這樣的代碼:git
這樣美不美呢?或許看着是還挺美的,可是若是須要修改,是否是人傻啦?github
那這樣的代碼呢?web
做爲一個對本身有必定要求的程序猿,是否是第一反應就是:ajax
規範不一,就會像下圖中的小鴨和小雞對話同樣,語言不通,一臉囧相。雞同鴨講也偏偏形容了人與人之間溝通的痛點,自說自話,沒法達成一致意見。再舉一個生活中的例子,交通規則靠左行駛仍是靠右行駛,二者孰好孰壞並不重要,重要的是必需要在統一的方向上通行,表面上限制了自由,但其實是保障了公衆的人身安全。試想,若是沒有規定靠右行駛,那樣的路況確定擁堵不堪,險象環生。一樣,過度自由隨意、天馬行空的代碼會嚴重的傷害系統的健康,影響到可擴展性以及可維護性。sql
衆所周知,互聯網公司的優點在於效率,它是企業核心競爭力。體如今產品開發領域,就是夠溝通效率和研發效率。對於溝通效率的重要性,能夠從程序猿三大 「編碼理念之爭」 提及:數據庫
在美劇《硅谷》中,有這樣的一個經典鏡頭:編程
Tab 鍵和空格鍵的爭議確實存在,而且在知乎上討論得火熱:寫代碼時,縮進使用 tab 仍是空格?
if 單語句是否須要換行,也是爭論不休的話題。相對來講,寫過格式縮進類編程語言的開發者, 更加習慣於不加大括號。《手冊》中明確 if/for 單行語句必須加大括號,由於單行語句的寫法,容易在添加邏輯時引發視覺上的錯誤判斷。此外,if 不加大括號還會有局部變量做用域的問題。
左大括號是否單獨另起一行?由於 Go 語言的強制不換行,在這點上,「編程理念之爭」 的硝煙味彷佛沒有那麼濃。若是必定要給一個理由,那麼換行的代碼能夠增長一行,對於按代碼行數考覈工做量的公司員工,確定傾向於左大括號前換行。《手冊》明確左大括號不換行!
這一章是對傳統意義上的代碼規範,包括變量命名、代碼風格、控制語句、代碼註釋等基本的變成習慣,以及從高併發場景中提煉出來的集合處理技巧與併發多線程的注意事項。
- 反例:
_name
/$name
/name_
/name$
儘管 $
能夠做爲標識符使用,然而咱們應該儘可能避免對其使用。
$
一般在編譯器生成的標識符名稱中使用,若是咱們也使用這個符號,可能會有一些意想不到的錯誤發生....package test; public class User$VIP { public static void main(String[] args) { User user = new User(); User.VIP vip = user.new VIP(); vip.print(); } } class User{ class VIP{ void print(){ System.out.println("成員類"); } } }
仔細閱讀如下,彷佛並無什麼問題,代碼也比較簡單,但正在咱們編譯的時候,IDEA提示咱們:
定義了重複的代碼?歸根到底,都是 $
惹的禍!由於 $
被編譯器所使用,在源文件(.java 文件)編譯成字節碼(.class 文件)後,會稱爲頂層類型與嵌套類型之間的鏈接符。例如,若是存在一個頂層類 A,在其內聲明瞭一個成員類 B,那麼編譯以後就會產生兩個 class 文件,分別爲 A.class
與 A$B.class
。
就本程序來講,會生成 3 個 class 文件(若是能夠編譯的話),分別是 User$VIP.class
(頂層類)、User.class
與 User$VIP.class
(User 類的成員類,也就是類 VIP)。因爲試圖存在兩個 User$VIP.class
因此纔會報錯!
變量命名所有大寫,單詞兼用下劃線隔開,力求予以表達完整清楚,不要嫌名字太長。
正例:MAX_STOCK_COUNT / PRIZE_NUMBER_EVERYDAY
反例:MAX_COUNT / PRIZE_NUMBER
抽象類命名使用 Abstract 或 Base 開頭;異常類命名使用 Exception 結尾;測試類命名以它要測試的類名開始,以 Test 結尾。
反例:定義爲基本數據類型
Boolen isDeleted;
的屬性,它的方法名稱也是isDeleted()
,RPC 框架在反向解析的時候,「誤覺得」 對應的屬性名稱是deleted
,致使屬性獲取不到拋出異常。
說明: 將設計模式體如今名字中,有利於閱讀者快速理解架構設計理念。
正例:
public class OrderFactory;
public class LoginProxy;
public class ResourceObserver;
正例:
接口方法簽名:void commit();
接口基礎變量:String COMPANY = "alibaba";
反例:
接口定義方法:public abstract void commit();
正例: CacheServiceImpl 實現 CacheServcie 接口
2):【推薦】 若是是形容能力的接口名稱,取對應的形容詞爲接口名(一般是 -able 的形式)。
正例: AbstractTranslator 實現 Translatable。
Long a = 2l;
寫得是數字的 21 仍是 Long 型的 2?說明: 大而全的變量類,非得使用查找功能才能定位到修改的常量,不利於理解和維護。
正例:緩存相關常量放在類 CacheConsts 下;系統配置相關常量放在 ConfigConsts 下。
public static void main(String[] args){ // 註釋的雙斜線與註釋內容之間有且僅有一個空格 // 縮進 4 個空格 String say = "hello"; // 運算符的左右必須有 1 個空格 int flag = 0; // 關鍵字 if 與括號之間必須有 1 個空格,括號內的 f與左括號、 // 0 與右括號之間不須要空格 if (flag == 0) { System.out.println(say); } // 左大括號前加空格且不換行;左大括號後換行 if (flag == 1) { System.out.println("world"); // 右大括號前換行,右大括號後有 else,不用換行 } else { System.out.println("ok"); // 在右大括號後直接結束,則必須換行 } }
正例:下例中實參的「one」,後邊必需要有一個空格。
method("one", "two", "three");
Intergre var = ?
在 -128~127 範圍內的賦值, Integer 對象是在 IntegerCache.cache 中產生的,會複用已有的對象,這個區間內的 Integer 值能夠直接使用 == 進行判斷,可是這個區間以外的全部數據,都會在堆上產生,並不會複用已有對象。這是一個大坑,推薦使用 equals 方法進行判斷。// 正例 Iterator<String> iterator = list.iterator(); while (iterator.hasNext()) { String item = iterator.next(); if (刪除元素的條件) { iterator.remove(); } } // 反例 List<String> list = new ArrayList<>(); list.add("1"); list.add("2"); for (String item : list) { // 若是把 1 改成 2 再試一下看看是否相同 if ("1".equals(item)) { list.remove(item); } }
if (condition) statements;
反例:判斷剩餘獎品數量等於 0 時,終止發放獎品,但由於併發處理錯誤致使獎品數量瞬間變成了負數,這樣的話,活動沒法終止。
// 正例:超過 3 層的 if-else 邏輯判斷代碼可使用衛語句、策略模式 // 狀態模式等來實現,其中衛語句實例以下: public void today() { if (isBusy()) { System.out.println("change time,"); return; } if (isFree()) { System.out.println("go to travel."); return; } System.out.println("stay at home to learn Java"); return; }
/**內容*/
格式,不得使用 //xxx
方式「安全生產,責任重於泰山。」 這句話一樣適用於軟件生產,本章主要說明編程中須要注意的比較基礎的安全準則。
說明: MySQL 在 Windows 下不區分大小寫,但在 Linux 下默認區分大小寫。所以,數據庫名、代表、字段名都不容許出現任何大寫字母,避免節外生枝。
正例: getter _ admin , task _ config , level 3_ name
反例: GetterAdmin , taskConfig , level 3 name
正例: tiger _ task / tiger _ reader / mpp _ config
正例:以下表,其中無符號值能夠避免誤存負數,且擴大了表示範圍。
對象 | 年齡區間 | 類型 | 表示範圍 |
---|---|---|---|
人 | 150 歲以內 | unsigned tinyint | 無符號值:0 到 255 |
龜 | 數百歲 | unsigned smallint | 無符號值:0 到 65535 |
恐龍化石 | 數千萬年 | unsigned int | 無符號值:0 到約 42.9 億 |
太陽 | 約 50 億年 | unsigned bigint | 無符號值:0 到約 10 的 19 次方 |
正例: where a =? and b =? order by c; 索引: a _ b _ c
反例:索引中有範圍查找,那麼索引有序性沒法利用,如: WHERE a >10 ORDER BY b; 索引 a _ b 沒法排序。
正例:若是 where a =? and b =? , a 列的幾乎接近於惟一值,那麼只須要單建 idx _ a 索引便可。
整個規約對本身來講都挺有用的,由於正好涉及到這方面,幸虧感受臉不怎麼疼。
瀏覽了一遍,仍是學習到了不少東西吧,上面也僅僅只是總結了對我本身比較收益,現階段我能吸取能實際感覺獲得的規約,若是想要 PDF 版的能夠在這裏下載:戳這裏
歡迎轉載,轉載請註明出處!
簡書ID:@我沒有三顆心臟
github:wmyskxz 歡迎關注公衆微信號:wmyskxz_javaweb 分享本身的Java Web學習之路以及各類Java學習資料