阿里巴巴Java開發手冊閱讀筆記
備註:筆記參考《阿里巴巴Java開發手冊終極版v1.3.0》
下載連結: https://pan.baidu.com/s/1k4ujejAkRaUjhUP1IK_Cvw 提取碼: hew3
一、程式設計規範
1、常量命名全部用大寫,單詞間用下劃線隔開
正例:MAX_FLOW_NUM
反例:MAX_NUM
2、抽象類命名以Abstract或Base開頭;異常類命名以Exception結尾
正例:AbstractBaseAction/BaseController
3、POJO類布林型別變數,都不要加is,否則部分框架解析會引起序列化錯誤
反例:isDelete
備註:需要注意
4、杜絕完全不規範的縮寫,避免產生歧義
反例:AbstractClass縮寫為AbsClass
反例:int a,a沒有意義,不可取
5、【推薦】如果模組、介面、類、方法使用了設計模式,在命名時體現出具體模式
說明:利於閱讀者理解架構設計理念
正例:public class OrderFactory
6、【推薦】介面類中的方法和屬性,不要加任何修飾符號(public也不要加),保持程式碼的簡介性。儘量不要在接口裡面定義變數,如果一定要定義變數,肯定是與介面方法相關,並且是整個應用的基礎常量。
7、【推薦】列舉類名建議加上Enum字尾,列舉類名需要全部大寫,單詞間用下劃線隔開
8、【參考】各層命名規約:
A)Service/DAO 層命名規約
1)獲取單個物件的方法用get做字首
2)獲取多個物件的方法用list做字尾
反例:dispatchOrderService.find();//查詢所有的排程記錄
3)獲取統計值的方法用count做字首
4)插入的方法用save/insert 做字首
5)刪除的方法用remove/delete 做字首
6)修改的方法用update 做字首
二、程式碼格式
1、任何二目、三目運算子的左右兩邊,都需要加一個空格
2、採用4個空格縮排,禁止使用tab字元
public static void main(String[] args) { // 縮排 4 個空格 String say = "hello"; // 運算子的左右必須有一個空格 int flag = 0; // 關鍵詞 if 與括號之間必須有一個空格,括號內的 f 與左括號, 0 與右括號不需要空格 if (flag == 0) { System.out.println(say); } // 左大括號前加空格且不換行;左大括號後換行 if (flag == 1) { System.out.println("world"); // 右大括號前換行,右大括號後有 else,不用換行 } else { System.out.println("ok"); // 在右大括號後直接結束,則必須換行 } }
3、註釋的雙斜線和註釋內容之間,有且只有一個空格
正例://獲取日期,姓名
4、單行字元數限制不超過120個,超出需要換行,換行時遵循如下原則:
第二行相對第一行縮排4個空格,從第三行開始,不再繼續縮排
正例:
@Query(" SELECT o FROM RecordStatus o "
+ " WHERE (o.relatedName like :relatedName) "
+ " AND (o.id = :id) "
+ " ORDER BY o.relatedName,o.relatedType,o.orderNum")
5、方法引數在定義和傳入時,多個引數逗號後必須加空格
正例:
super.update(operateType, params, id, newObjJson);
三、OOP規範
1、避免通過一個類的物件訪問類的靜態變數或靜態方法
2、可變引數必須放在引數列表的最後(提倡進來不使用可變引數程式設計)
正例:
public User getUsers(String type, Integer... ids) {...}
備註:【可變引數】,三個點,解決引數個數不確定的問題
3、equlas方法容易拋空指標,應使用常量或確定值的物件放在左邊,再呼叫equlas方法
String a = "hello";
String b = null;
正例:a.equlas(b); //結果是false
反例:b.equlas(a); //結果是java.lang.NullPointerException
解釋:null不是String物件,null呼叫方法系統出現空指標異常,所以我們把明確的一定有值的那個變數放在前面。
4、基本資料型別和包裝資料型別的使用標準:
1)所有的POJO類資料必須使用包裝資料型別
2)【推薦】所有的區域性變數使用基本資料型別
5、POJO必須重寫toString方法
說明:如果沒重寫toString方法,返回的是一串看不懂的數字(Java物件的記憶體地址)。重寫toString後,返回的是物件和值。
原始:
這是沒有tostring重寫實體類的時候!
呼叫實體類返回的是:[email protected]
重寫後:
這是有tostring重寫實體類的時候!
呼叫實體類返回的是:toStringTest [name=zout, sex=man, No=1]
詳情可參考:
https://blog.csdn.net/si444555666777/article/details/81531601
6、當一個類有多個構造方法,應該按順序放置在一起
7、類內方法的定義順序是:公有方法或保護方法 > 私有方法 > getter/setter 方法
說明:公有方法是類的呼叫者最關心的,應該首屏展示。私有方法外部一般不需要關心。
8、字串拼接,首選StringBuilder的append方法
備註:
1)加號 “+” 拼接 更適合我們的閱讀習慣
2)StringBuffer append() 方法,適合大批量資料處理
參考:
字串拼接5種方法比較:https://www.cnblogs.com/twzheng/p/5923642.html
String,StringBuilder,StringBuffer區別:
String:少量字串操作
StringBuilder:單執行緒下大量操作
StringBuffer: 多執行緒下大量操作
https://www.cnblogs.com/su-feng/p/6659064.html
9、類成員與方法訪問控制從嚴
1)如果不允許外部直接通過new來建立物件,那麼構造方法必須是private
2)工具類不允許有public或default構造方法
備註:工具類是一系列靜態成員或方法的集合,意味著它不可以被例項化
3)類非static成員變數,並且與子類共享,必須是protected
4)類非static成員變數,並且僅在本類使用,必須是private
5)若static成員變數,必須考慮是否為final
四、集合處理
1、關於hashCode和equals的處理
1)只要重寫equals,就必須重寫hashCode
參考:https://blog.csdn.net/freelander_j/article/details/52211010
2、不要在foreach迴圈裡進行元素的remove/add操作。remove元素請使用Iterator方式,如果併發操作,需要對Iterator物件加鎖。
正例:
Iterator<String> iterator = list.iterator();
while (iterator.hasNext()) {
String item = iterator.next();
if (刪除元素的條件) {
iterator.remove();
}
}
反例:
List<String> list = new ArrayList<String>();
list.add("1");
list.add("2");
for (String item : list) {
if ("1".equals(item)) {
list.remove(item);
}
}
3、集合初始化時,指定集合初始值大小
備註:由於 沒有設定容量 初始大小,隨著元素不斷增加容 量 7次被迫擴大, resize需要重建 hash表,嚴重影響效能。
注意:指定初始值大小,不影響list.size()的數值
疑問:自己測試了200萬條資料,效能進差別50%,所以對此有疑問。
- Map類集合K/V 能不能儲存null值的情況,如下表格:
集合 |
Key |
Value |
執行緒安全 |
TreeMap |
不允許為null |
允許為null |
非執行緒安全 |
HashMap |
允許為null |
允許為null |
非執行緒安全 |
LindedHashMap |
允許為null |
允許為null |
非執行緒安全 |
HashTable |
不允許為null |
不允許為null |
執行緒安全(效率低) |
五、控制語句
1、在一個switch塊內,每個case要麼通過break/return終止,要麼註釋說明程式將繼續執行到哪一個case位置;
在一個switch塊內,必須包含一個default語句並且放在最後,及時什麼程式碼也沒有。
/*
語法:
switch(表示式){
case 值1:
表示式的值和 值1匹配上了,需要執行的程式碼;
break;
case 值2:
表示式的值和 值2匹配上了,需要執行的程式碼;
break;
case 值3:
表示式的值和 值3匹配上了,需要執行的程式碼;
break;
default:
如果表示式的值和以上的case後面的值都沒有匹配上,那麼就執行這裡的程式碼。
break;
}
* */
* //不寫break會穿透到下一個break
2、表達異常的分支時,少用if-else方式
超過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("good job!");
return;
}
備註:
【衛語句】把複雜的條件表示式拆分成多個條件表示式,比如一個很複雜的表示式,嵌套了好幾層的if - then-else語句,轉換為多個if語句,實現它的邏輯,這多條的if語句就是衛語句. 使用衛語句減少層級巢狀。
六、註釋規約
1、類、類屬性、類方法的註釋必須使用javadoc規範,使用/**內容*/格式,不得使用//xx方式
2、所有的抽象方法,必須使用javadoc註釋,除了返回值、引數、異常說明外
3、所有的類都必須新增建立者和建立日期
4、方法內部單行註釋,使用//註釋
5、所以列舉型別欄位都必須有註釋,說明每個資料項的用途
6、程式碼修改的同時,註釋也要進行相應的修改,尤其是引數、返回值、異常、核心邏輯