Effective Java
今回は「項目28:API の柔軟性向上のために境界ワイルドカードを使用する」。 項目28はけっこう長いので2回に分割した。 不変性による弊害 項目25で説明したように Java のジェネリックスは不変です。 Object は Number のスーパータイプですが、List<Object></object>…
ポイント ジェネリックメソッドを利用しよう ジェネリックメソッドは型推論を行う ジェネリック static ファクトリーメソッド 型推論を利用したテクニック ただし、現代にいるならダイヤモンド演算子を使うべき ジェネリックシングルトンファクトリー それぞ…
ジェネリック型を使う 今回は簡単にジェネリック型の使い方・書き方について説明します。 項目6での説明に利用したスタックの実装を、ジェネリックスを用いた実装に置き換えることを例としてみます。 ジェネリックスを利用しない元のスタック実装は以下の通…
ジェネリックスと配列 前回の記事 ではジェネリックス型の不変、共変、反変について説明しました。 今回はジェネリクス型のリスト(List<E>)と配列の性質の違いについて説明します。 前回も説明したように、Java のジェネリックス型は不変である一方、配列は共</e>…
今回は「項目24:無検査警告を取り除く」。 ポイント 無検査警告は必ず取り除く 方法1:コードを変更して警告を取り除く 方法2:注意して @SuppressWarnigns アノテーションで警告を抑制する ジェネリックスに対するコンパイル警告 ジェネリックスを利用…
第5章から Effective Java シリーズ再開。第5章はジェネリックスについて。 今回は「項目23:新たなコードで原型を使用しない」。 ポイント ジェネリックスを積極的に使う 実行時ではなくコンパイル時にエラーをチェックできる 原型は利用しない 非境界…
クラスの中に定義されたクラスを『ネストしたクラス』と呼ぶ。 ネストしたクラスは4種類に分類できるが、非 static メンバークラスよりも static メンバークラスを利用するべき。 ネストしたクラス ネストしたクラスには以下の4種類があり、static のメン…
戦略パターンを実現するため、関数オブジェクトを利用する。 関数オブジェクト 多くのプログラミング言語では、関数ポインタ、委譲、ラムダ式と呼ばれるような機構を利用して、関数自体の受け渡しが可能になっている。 関数自体をある関数に与えることで、呼…
クラスが2つ以上の特性を持っている場合、タグフィールドを保持するよりも、クラス階層を利用するべき。 タグ付クラス タグ付クラスとはクラスが2つ以上の特性を持っていて、タグフィールドを保持することで、それらを区別するように実装されているクラス…
インタフェースは、その実装クラスのインスタンスで何ができるかだけを述べるべきである。 その他の目的、たとえば定数インタフェースなどには利用しない。 定数インタフェース メソッドを持たず、static final の定数を外部に提供しているだけのインタフェ…
Java では抽象クラスよりも、インタフェースを利用するべき。 抽象クラスとインタフェース 抽象クラスとインタフェースには以下の違いがある。 抽象クラスはメソッドの実装を含むことが許されるが、インタフェースは許されない 抽象クラスを実装するためには…
継承させることを意図するクラスを作成するときは、継承のために設計し、文書化する。 そうでない場合には継承させないようにする。 自己利用(self-use)の文書化 クラスはオーバーライド可能なメソッドの自己利用を文書化する必要がある。 個々の public …
継承よりもコンポジションを選ぶべきである。 継承の利用 継承はコードを再利用するための一般的な手法だが、常に最適なものとは限らない。 継承を安全に利用することができるのは以下の場合である。 スーパークラスもサブクラスも特定のパッケージ配下にあ…
クラスの可変性は最小限にするべきである。 不変クラス 不変クラスとは、そのインスタンスを変更できないという性質をもつクラス。 インスタンスが生成された時点ですべての情報を持っていて、インスタンスの生存期間中はそれらの情報が変化しないことが保証…
クラスがパッケージの外からアクセス可能ならば(public ならば)、ゲッターとセッターを提供するべき。 public なクラスがデータフィールドを公開すると、その内部的な表現を永久に変更できなくなる。 一方、クラスがパッケージプライベート・private のネ…
ここから第4章「クラスとインターフェス」。 クラスとインタフェースは Java の中心に位置し、抽象化の基本となる要素。 この章では、クラス・インタフェースが利用可能で、頑強で、柔軟になるような指針を議論する。 最初の項目は情報隠蔽・カプセル化に関…
Comparable インタフェースの compareTo を実装するとインスタンスが順序を持つようになる。 第3章で議論した他のメソッドとは異なり、compareTo メソッドは Object では宣言されていない。 ただし、Comparable を実装すると、多くの一般的なアルゴリズムや…
本項目では正しく機能する clone メソッドを、どのように、いつ実装するかを議論する。 Cloneable インタフェース Cloneable インタフェースはオブジェクトが複製を許可していることを示す。 ただし、Cloneable インタフェース自体は空のインタフェースであ…
toString をオーバライドして意味のある文字列を返すようにする。 toString のオーバーライド java.lang.Object は toString() を実装しているが、ユーザーにとってよい情報を返すわけではない。 Object obj = new Object(); // 「クラス名@ハッシュコード値…
equals をオーバーライドする時は、hashCode メソッドを必ずオーバーライドしなければならない。 オーバーライドしない場合、Object.hashCode の一般契約を破ることになり、HashMap、HashSet、HashTable など、hashCode の一般契約に基づくコレクションが適…
第3章『すべてのオブジェクトに共通のメソッド』に入る。 第3章は、Object.equals()、Object.hashCode()、Object.toString()、Object.clone() について、いつ、どのようにオーバーライドするかを説明する。 finalize も同様のものだが、すでに項目7で議論…
Java のファイナライザは予想不可能で、危険であり、一般的には使う必要はない。 C++ プログラマは Java のファイナライザを C++ のデストラクタと対応付けて考えてしまいがちだが、それは大きな間違いである。 C++ のデストラクタはコンストラクタに対応す…
メモリリークを回避するため廃れたオブジェクトの参照は取り除かなければならない。 C や C++ から、ガーベージコレクション(GC)を持つ言語に切り替えると、メモリ管理について考える必要がないように感じることがあるが、それは間違いだ。 次のスタック実…
機能的に同じオブジェクトを、必要になるごとに再生成するのは避ける。 よくない例 極端にだめな例としては以下の様なコードがある。 // だめな例 String s = new String("stringee"); "stringee" 自身が String オブジェクトであり、String コンストラクタ…
static のメソッドと static なフィールドだけからなるクラスを書く場合は private コンストラクタでインスタンス化不可能をクライアントに強制するべきである。 static ユティリティクラス そのようなクラスは悪く評価されていることもあるが、java.lang.Ma…
シングルトンは、手短にいえば厳密に一度しかインスタンスが生成されないクラス。 ただし、クラスをシングルトンにするとデメリットも多々あるため本当に必要な場合のみ行うこと。 伝統的なシングルトン実装 Java の リリース 1.5 より前はシングルトンを実…
多くのオプションパラメータを持つオブジェクトを生成する場合はビルダーパターンを利用することを検討する。 テレスコーピングパターン 多くのオプションパラメータが存在するとき、伝統的にはテレスコーピングコンストラクタと呼ばれるパターンが利用され…
追記:2018年2月16日 Effective Java 3rd Edition を踏まえて内容をアップデートした記事を書きました。 こちらをご覧ください。 www.thekingsmuseum.info オブジェクトを生成するため、public コンストラクタの代わりに static ファクトリーメソッドを提供…
追記:2018年1月21日 Effective Java 3rd Edition を踏まえて内容をアップデートした記事を書きました。 こちらをご覧ください。 www.thekingsmuseum.info 第一章は前置き話がメイン。 第1章:はじめに この本の特徴は多くのデザインパターンとイディオムを…