Effective Javaの要点ピックアップ

Effective Java 第3版 「ほぼ全章」を「読みやすい日本語」で説明してみました

https://qiita.com/nyandora/items/3e5ec76ca3881bc17924

本にも載っているよ、と説明したい際に。

オブジェクト生成まわり

  • コンストラクタよりstaticファクトリメソッドで
  • コンストラクタパラメータが多いときはビルダーで
  • シングルトンはenumかprivateのコンストラクタで
  • staticなメソッドとフィールドだけのクラスはprivateのコンストラクタでインスタンス化できないように
  • リソースは直接結びつけるよりも依存性注入で
  • オブジェクト生成は最低限に
  • 使われなくなったオブジェクト参照は取り除く
  • ファイナライザとクリーナーは使わない
  • try-finallyよりtry-with-resourcesを使う

オブジェクト共通メソッドまわり

  • equalsをオーバーライドするときは一般的な要件に従う
  • equalsをオーバーライドするときはhashCodeを常にオーバーライドする
  • toStringを常にオーバーライドする
  • cloneのオーバーライドは原則NG。もしする必要がある場合は注意する
  • Comparableの実装を検討する

クラスやインターフェースまわり

  • クラスとメンバーへのアクセス可能性は最小限に
  • publicのクラスではpublicのフィールドではなくアクセッサーメソッドで
  • 可変オブジェクトは最小限に
  • 継承よりもコンポジション
  • 継承する場合は継承される前提の設計および文書化する、でなければ継承を禁止する
  • 抽象クラスよりインタフェースで
  • 将来を見越したインタフェースを設計する
  • タグ付きクラスにせずクラス階層を分ける
  • 非staticのメンバークラスよりもstaticのメンバークラスを
  • ソースファイルを単一のトップレベルのクラスに限定する

ジェネリクスまわり

enumアノテーションまわり

  • int定数の代わりにenum
  • ordinalの代わりにインスタンスフィールドで
  • ビットフィールドの代わりにEnumSetで
  • ordinalをインデックスにする代わりにEnumMapで
  • enumをインタフェースで拡張可能に
  • 命名パターンよりアノテーション
  • 常にOverrideアノテーションを付けること
  • 型を定義するためにマーカーインターフェースで

ラムダやストリームまわり

  • 無名クラスよりラムダで
  • ラムダよりメソッド参照で
  • 標準の関数型インターフェースで
  • ストリームを注意して使う
  • ストリームは副作用のない関数で
  • 戻り値の型はStreamよりCollectionで
  • ストリームの並列化は注意する

メソッドまわり

  • パラメータの正当性を検査する
  • 必要な場合、防御的にコピーする
  • メソッドのシグニチャを注意深く設計する
  • オーバロードを注意して使う
  • 可変長引数を注意して使う
  • nullではなく、空コレクションか空配列を返す
  • Optionalを注意して返す
  • すべての公開API要素に対してドキュメントコメントを書く

全般

  • ローカル変数のスコープは最小限に
  • forループよりfor-eachループで
  • ライブラリを知り、ライブラリを使う
  • 正確な答えが必要である場合、floatとdoubleは避ける
  • ボクシングされた基本データより基本データ型で
  • 他の型が適切な場所では文字列型を避ける
  • 文字列結合のパフォーマンスに用心する
  • インターフェースでオブジェクトを参照する
  • リフレクションよりインターフェースで
  • ネイティブメソッドを注意して使う
  • 注意して最適化する
  • 一般的に受け入れられている命名規約を守る

例外まわり

  • 例外的な状態だけ例外を使う
  • 回復可能な状態にはチェック例外で、プログラミングエラーには実行時例外で
  • チェック例外を不必要に使うのは避ける
  • 標準的な例外を使う
  • 抽象概念に適した例外をスローする
  • 各メソッドがスローするすべての例外をドキュメント化する
  • 詳細メッセージにエラー記録情報を含める
  • エラーアトミック性に努める
  • 例外を無視しない

スレッドまわり

  • 共有された可変データへのアクセスを同期する
  • 過剰な同期は避ける
  • スレッドよりエグゼキュータ/タスク/ストリームで
  • waitやnotifyより並行処理ユーティリティで
  • スレッド安全性をドキュメント化する
  • 遅延初期化を注意して使う
  • スレッドスケジューラに依存しない

シリアライズまわり