Java開發手冊學習筆記

目錄

一、編程規約

(一)命名風格

對於獲取對象不管是多個還是單個是否都可以使用get爲前綴,後續單詞已複數結尾。​(二)常量定義

(三)代碼格式

(四)空格格式

(五) OOP 規約

雙進度浮點數double使用bigDecimal類

關於 hashCode 和 equals 的處理,遵循如下規則: (疑惑)

ArrayList 的 subList 結果不可強轉成 ArrayList,否則會拋出 ClassCastException 異常,即 java.util.RandomAccessSubList cannot be cast to java.util.ArrayList。

使用 Map 的方法 keySet()/values()/entrySet()返回集合對象時,不可以對其進行添加元素操作,否則會拋出 UnsupportedOperationException 異常。(如果要進行操作的話就需要使用對象鎖)

Collections 類返回的對象,如:emptyList()/singletonList()等都是 immutablelist,不可對其進行添加或者刪除元素的操作。

使用集合轉數組的方法,必須使用集合的 toArray(T[] array),傳入的是類型完全一致、長度爲 0 的空數組。

使用工具類 Arrays.asList()把數組轉換成集合時,不能使用其修改集合相關的方法,它的 add/remove/clear 方法會拋出 UnsupportedOperationException 異常。

asList 的返回對象是一個 Arrays 內部類,並沒有實現集合的修改方法。Arrays.asList 體現的是適配器模式,只是轉換接口,後臺的數據仍是數組。

(六) 併發處理

SimpleDateFormat 是線程不安全的類,一般不要定義爲 static 變量,如果定義爲static,必須加鎖,或者使用 DateUtils 工具類。

必須回收自定義的 ThreadLocal 變量,尤其在線程池場景下,線程經常會被複用,如果不清理自定義的 ThreadLocal 變量,可能會影響後續業務邏輯和造成內存泄露等問題。 儘量在代理中使用 try-finally 塊進行回收。 (疑惑)


一、編程規約

(一)命名風格

對於獲取對象不管是多個還是單個是否都可以使用get爲前綴,後續單詞已複數結尾。

(二)常量定義

常量類全部保存到constant目錄下,如果是跨應用共享常量需要放置到二方庫中,通常是client.jar中的constant目錄下。

(三)代碼格式

(參考wiki)

(四)空格格式

在等號兩邊第一個都是空格

int second = (int)first + 2;
方法參數在定義和傳入時,多個參數逗號後邊必須加空格。
method(args1, args2, args3); 

(五) OOP 規約

避免通過一個類的對象引用訪問此類的靜態變量或靜態方法,無謂增加編譯器解析
成本,直接用類名來訪問即可。
 
所有整型包裝類對象之間值的比較,全部使用 equals 方法比較。
說明:對於 Integer var = ? 在-128 至 127 範圍內的賦值,Integer 對象是在 IntegerCache.cache 產
生,會複用已有對象,這個區間內的 Integer 值可以直接使用==進行判斷,但是這個區間之外的所有數
據,都會在堆上產生,並不會複用已有對象,這是一個大坑,推薦使用 equals 方法進行判斷。
爲什麼IntegerCache.cache裏面是-128至127的內容?
因爲存放在一個byte字節裏面
 
浮點數之間的計算使用bigDecimal類
 BigDecimal a = new BigDecimal("1.0");
 BigDecimal b = new BigDecimal("0.9");
 BigDecimal c = new BigDecimal("0.8");
 BigDecimal x = a.subtract(b);
 BigDecimal y = b.subtract(c);

 

雙進度浮點數double使用bigDecimal類

優先推薦入參爲 String 的構造方法,或使用 BigDecimal 的 valueOf 方法,此方法內部其實執行了
Double 的 toString,而 Double 的 toString 按 double 的實際能表達的精度對尾數進行了截斷。

BigDecimal recommend1 = new BigDecimal("0.1");
BigDecimal recommend2 = BigDecimal.valueOf(0.1); 
 
循環體內,字符串的連接方式,使用 StringBuilder 的 append 方法進行擴展。
說明:下例中,反編譯出的字節碼文件顯示每次循環都會 new 出一個 StringBuilder 對象,然後進行append 操作,最後通過toString 方法返回 String 對象,造成內存資源浪費
 

關於 hashCode 和 equals 的處理,遵循如下規則: (疑惑)

1) 只要覆寫 equals,就必須覆寫 hashCode。
2) 因爲 Set 存儲的是不重複的對象,依據 hashCode 和 equals 進行判斷,所以 Set 存儲的對象必須覆寫這兩個方法。
3) 如果自定義對象作爲 Map 的鍵,那麼必須覆寫 hashCode 和 equals。
說明:String 已覆寫 hashCode 和 equals 方法,所以我們可以愉快地使用 String 對象作爲 key 來使用。
默認的equels方法比較是不是同一個對象,==(比較的是對象的hashCode是否一樣),不比較其內容是否是一樣的。
 
 

ArrayList 的 subList 結果不可強轉成 ArrayList,否則會拋出 ClassCastException 異常,即 java.util.RandomAccessSubList cannot be cast to java.util.ArrayList

 
 
 

使用 Map 的方法 keySet()/values()/entrySet()返回集合對象時,不可以對其進行添加元素操作,否則會拋出 UnsupportedOperationException 異常。(如果要進行操作的話就需要使用對象鎖)

 
 

Collections 類返回的對象,如:emptyList()/singletonList()等都是 immutablelist,不可對其進行添加或者刪除元素的操作。

反例:如果查詢無結果,返回 Collections.emptyList()空集合對象,調用方一旦進行了添加元素的操作,就
會觸發 UnsupportedOperationException 異常。
 

使用集合轉數組的方法,必須使用集合的 toArray(T[] array),傳入的是類型完全一致、長度爲 0 的空數組。

反例:直接使用 toArray 無參方法存在問題,此方法返回值只能是 Object[]類,若強轉其它類型數組將出
ClassCastException 錯誤。
說明:使用 toArray 帶參方法,數組空間大小的 length
1等於 0,動態創建與 size 相同的數組,性能最好。
2大於 0 但小於 size,重新創建大小等於 size 的數組,增加 GC 負擔。Java 開發手冊12/44
3等於 size,在高併發情況下,數組創建完成之後,size 正在變大的情況下,負面影響與上相同。
4大於 size,空間浪費,且在 size 處插入 null 值,存在 NPE 隱患。
 
 

使用工具類 Arrays.asList()把數組轉換成集合時,不能使用其修改集合相關的方法,它的 add/remove/clear 方法會拋出 UnsupportedOperationException 異常。

asList 的返回對象是一個 Arrays 內部類,並沒有實現集合的修改方法。Arrays.asList 體現的是適配器模式,只是轉換接口,後臺的數據仍是數組。

1)如果真的必須使用的話,需要包裝一層
List<String> list1 = new ArrayList<>(Arrays.asList("qqq", "www", "eee"));
list1.add("aaa1");
list1.forEach(str -> System.out.println(str));

2)Arrays.asList()這個方法,最好不要用於數組轉list。一般適用於初始化一個定長list,並賦值。

 

(六) 併發處理

SimpleDateFormat 是線程不安全的類,一般不要定義爲 static 變量,如果定義爲static,必須加鎖,或者使用 DateUtils 工具類。

正例:注意線程安全,使用 DateUtils。亦推薦如下處理:
private static final ThreadLocal<DateFormat> df = new ThreadLocal<DateFormat>() {
        @Override
        protected DateFormat initialValue() {
        return new SimpleDateFormat("yyyy-MM-dd");
    }
}; 

說明:如果是 JDK8 的應用,可以使用 Instant 代替 Date,LocalDateTime 代替 Calendar,DateTimeFormatter 代替 SimpleDateFormat,官方給出的解釋:simple beautiful strong immutable thread-safe。

必須回收自定義的 ThreadLocal 變量,尤其在線程池場景下,線程經常會被複用,如果不清理自定義的 ThreadLocal 變量,可能會影響後續業務邏輯和造成內存泄露等問題。 儘量在代理中使用 try-finally 塊進行回收。 

解釋:如果threadLocal使用在全局的情況下的話通過static定義就不需要考慮回收。

正例:
objectThreadLocal.set(userInfo);
try {
    // ...
} finally {
    objectThreadLocal.remove();
} 

 

併發修改同一記錄時,避免更新丟失,需要加鎖。要麼在應用層加鎖,要麼在緩存加鎖,要麼在數據庫層使用樂觀鎖,使用 version 作爲更新依據。

 

(七) 控制語句

在高併發場景中,避免使用”等於”判斷作爲中斷或退出的條件。(疑惑)

說明:如果併發控制沒有處理好,容易產生等值判斷被“擊穿”的情況,使用大於或小於的區間判斷條件

來代替。
 
 

(八) 註釋規約

類、類屬性、類方法的註釋必須使用 Javadoc 規範,使用/**內容*/格式,不得使用// xxx 方式。
 

(九) 其它

在使用正則表達式時,利用好其預編譯功能,可以有效加快正則匹配速度。
說明:不要在方法體內定義:Pattern pattern = Pattern.compile(“規則”);
 
後臺輸送給頁面的變量必須加$!{var}——中間的感嘆號。
說明:如果 var 等於 null 或者不存在,那麼${var}會直接顯示在頁面上。 

 

二、異常日誌

(一) 異常處理

Java 類庫中定義的可以通過預檢查方式規避的 RuntimeException 異常不應該通過 catch 的方式來處理,比如:NullPointerExceptionIndexOutOfBoundsException 等等。
 

持續更新。。。。

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