Java中級者以上の必須本である、Effective Java 第3版に Kindle版が出たので、まとめる。
前:Effective Java 第3版 第7章ラムダとストリーム
次:Effective Java 第3版 第9章プログラム一般
項目49 パラメータの正当性を検査する
- publicとprotectedのメソッドに対しては、パラメータ値に関する制約が守られていない場合にスローされる例外をJavadocの
@throws
タグを使って文章化する。一般的にその例外は、IllegalArgumentException
、IndexOutOfBoundsException
、NullPointerException
。 - Java7で追加された、
Objects.requireNonNull
メソッドは柔軟かつ便利なので、null検査を手作業で行う必要はない。
// strategyがnullの場合は、NullPointerExceptionを投げる
this.strategy = Objects.requireNonNull(strategy, "strategy must not be null.")
- Java9では範囲検査機構が、
java.util.Objects
に追加された。checkFromIndexSize
、checkFromToIndex
、checkIndex
の3つのメソッドから構成され、リストと配列のインデックスが範囲内かどうかチェックする。 - publicではないメソッドは、アサーションを使ってパラメータを検査すべきである。
項目50 必要な場合、防御的にコピーする
- Dateクラスのような可変なオブジェクトがパラメータとして入ってきた場合、防御的にコピーすることが重要である。
項目51 メソッドのシグニチャを注意深く設計する
- メソッド名を注意深く選ぶ。長いメソッド名は避ける。
- 便利なメソッドを提供しすぎない。個々のメソッドは「自分の役割を果たす」べきで、メソッドが多いと、テスト、保守を困難にする。
- 長いパラメータのリストは避ける。4個以下を目標にする。同一の型のパラメータが何個も続くのは有害である。過度に長いパラメータのリストを短くするには、以下の三つの技法がある。
- メソッドを分割して、各メソッドはパラメータのサブセットだけを必要とするようにする。
- パラメータの集まりを保持するヘルパークラスを作成する。
- Builderパターンをオブジェクト生成からメソッド呼び出しに適用する。
- パラメータ型は、クラスよりもインタフェースを選ぶ。パラメータを定義するために適切なインタフェースが存在する場合、そのインタフェースを実装したクラスよりは、そのインタフェースを使う。(例:HashMap→Map)
- booleanの意味がメソッド名から明らかでなければ、booleanよりも二つの要素を持つenum型を使う。
項目52 オーバーロードを注意して使う
- オーバーロードで、どのメソッドが呼び出されるかの選択は、コンパイル時に行われる。
Collection
インスタンスで、中身がArrayList
の場合には、ArrayList
を引数メソッドをうまく呼び出すことができない。 - 安全で保守的な方針は、同じパラメータ数の二つのオーバーロードされたメソッドを提供しない。オーバーロードする代わりに、異なる名前のメソッド名にする。
項目53 可変長引数を注意して使う
- 可変長引数メソッドで、1つ以上の引数が必要な時、実行時にしかチェックできないのが問題。
- 必須パラメータの後に、可変長引数を置く。
項目54 nullではなく、空コレクションか空配列を返す
- 空コレクションや空配列の代わりに、nullを返さない。
- nullだとAPIの使用が困難になり、パフォーマンスの利点もない。
項目55 オプショナルを注意して返す
- 値を持たないオブジェクトの表現方法は3つ。
- null(NullPointerExceptionの危険)
- Exception(コストが高い)
- Optional(java8から)
-
Optional.empty()
で空。Optional.of(value)
でvalueを含むOptional。 -
Optional.ofNullable(value)
は、valueがnullかどうかにより、上記のいずれかを判断して返す。 - Optionalを返すメソッドでは、nullを返してはならない。
- ボクシングされた基本データ型を含むオプショナルを返すのは、ボクシングを2レベル行うので高くつく。そのために、基本データ型の
OptionalInt
、OptionalLong
、OptionalDouble
が用意されている。 - 戻り値以外でOptionalを使うのはまれであるべき。
項目56 すべての公開API要素に対してドキュメントコメントを書く
- すべての公開されているクラス、インタフェース、コンストラクタ、メソッド、フィールド宣言の前に、ドキュメントコメントを書かなければならない。
- メソッドに関するドキュメントコメントは、メソッドとそのクライアント間の契約を簡潔に記述すべき。
- メソッドのすべての事前条件、事後条件、副作用を列挙する。
-
@param
、@return
、@throws
タグを書かれるべき。 - ドキュメントコメントはHTMLに変換されるので、HTMLタグが使える。
- 継承のためにクラスを設計するときは、自己利用パターンを文書化しなくてはならない。そのために、
@implSpec
を使う。 - HTMLのメタ文字(
<``>``&
など)を使うときは、@literal
タグで囲む。例){@literal |r| < 1}