Java標準ライブラリ

最終更新: 2021-06-11 09:05:39 +0800 +0800
原文は英語で書かれています。あなたはAI翻訳版を読んでいます。

小さなライブラリのコントラクトは、APIの表面積よりも正しさを左右することが 頻繁にあります。以下のルールは、よくあるJava統合の失敗を防ぎます。

オブジェクトのコントラクト #

equalsは、反射的、対称的、推移的、一貫性があり、nullに対してfalseで なければなりません。2つのオブジェクトが等しい場合、それらは同じ 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>>は、1つの列挙型に対して、型安全な順序付けと操作を Enumに提供します。EnumSetとEnumMapは、その閉じたキー空間を活用し、 列挙子の宣言順序を保持します。列挙型を対象とする場合は、HashSetや HashMapよりもこれらを優先してください。

コレクションとスレッド #

Thread.Stateは、BLOCKED、WAITING、TIMED_WAITINGなど、JVMレベルの状態を 報告します。これは観測用であり、同期プロトコルではありません。スレッドの 協調には、join、future、ラッチ、または構造化された所有関係を使用してください。

Mapがnullキーまたは値を許可するかどうかは、実装固有です。 HashMapは1つのnullキーを許可しますが、ConcurrentHashMapはnullキーと null値を拒否します。また、TreeMapは自然順序付けの場合にnullキーを拒否する ことがあります。Mapインターフェースのオプション操作が成功すると仮定せず、 選択した実装のコントラクトを確認してください。

Arrays.asList(array)は、指定されたオブジェクト配列を基盤とする固定サイズの リストを返します。setはその配列を更新しますが、addとremoveは失敗します。 int[]を渡すと、可変長引数がプリミティブ配列をボックス化しないため、1要素の List<int[]>が作成されます。ボックス化された値のリストが必要な場合は、 Arrays.stream(ints).boxed().toList()を使用してください。

参考資料 #

コメント

GitHub で閲覧・コメントする(投稿にはログインが必要です)