Java 標準函式庫

最後更新: 2021-06-11 09:05:39 +0800 +0800
原文以英文撰寫。您正在閱讀AI翻譯版本。

小型函式庫的契約往往比 API 表面更能決定正確性。以下規則可避免常見的 Java 整合失敗。

物件契約 #

equals 必須具備反身性、對稱性、傳遞性與一致性,並且對null回傳 false。 如果兩個物件相等,它們必須具有相同的hashCode;因此,在將值作為雜湊鍵之前, 應同時覆寫這兩個方法。物件作為映射鍵期間,不要變更參與相等性判定的欄位。 如果繼承會破壞對稱性,應優先使用組合而非繼承。

Object.clone會執行欄位複製,且與建構函式、繼承和可變欄位的配合不佳。 應優先使用複製建構函式或命名為copyOf的工廠方法。陣列是範圍有限的例外, 因為其clone具有可預測的淺陣列契約。

文字、正規表示式與字串 #

對於會重複使用的Pattern,應先進行編譯。Matcher.matches()要求整個輸入都符合, 而find()會搜尋下一個符合的區域。Pattern.quote(value)會跳脫放入正規表示式的 字面文字;Matcher.quoteReplacement(value)會跳脫替代字串。兩者不可互換。

自 JDK 9 起,HotSpot 的String實作使用緊湊字串:透過byte[]加上編碼標記, 可以緊湊地表示 Latin-1 文字,其他情況則使用 UTF-16。這是實作細節;Java String仍然是 UTF-16 程式碼單位的序列,且必須在 I/O 邊界明確進行Charset轉換。

計數器與列舉集合 #

AtomicLong提供一個精確且線性一致的值。LongAdder會在競爭下將更新分散到 多個儲存格,因此更新具有更好的擴充性,但與更新同時執行的sum()不是原子快照。 計量指標使用LongAdder;當每個觀測到的總數都會驅動正確性判定時,使用 AtomicLong。

Enum<E extends Enum<E>>為單一列舉型別提供型別安全的排序與操作。EnumSet與 EnumMap利用這個封閉的鍵空間,並保留列舉宣告順序;對於列舉網域,應優先使用 它們,而不是HashSet和HashMap。

集合與執行緒 #

Thread.State會回報BLOCKED、WAITING和TIMED_WAITING等 JVM 層級狀態; 它是觀察機制,而非同步協定。應使用join、future、閂鎖或結構化擁有權來協調執行緒。

Map是否允許null鍵或值取決於實作:HashMap允許一個 null 鍵,而 ConcurrentHashMap拒絕 null 鍵和值;在自然排序下,TreeMap也可能拒絕 null 鍵。不要假設Map介面的選用操作一定成功,而應驗證所選實作的契約。

Arrays.asList(array)會回傳由提供的物件陣列支援的固定大小清單。set會更新 該陣列,但add和remove會失敗。傳入int[]會建立包含一個元素的List<int[]>, 因為可變參數不會將基本型別陣列裝箱。需要裝箱值清單時,請使用 Arrays.stream(ints).boxed().toList()。

參考資料 #

評論

在 GitHub 上閱讀或評論(發表評論需要登入)