The King's Museum

ソフトウェアエンジニアのブログ。

Effective Java

【Effective Java】項目28:API の柔軟性向上のために境界ワイルドカードを使用する(その1)

今回は「項目28:API の柔軟性向上のために境界ワイルドカードを使用する」。 項目28はけっこう長いので2回に分割した。 不変性による弊害 項目25で説明したように Java のジェネリックスは不変です。 Object は Number のスーパータイプですが、List<Object></object>…

【Effective Java】項目27:ジェネリックメソッドを利用する

ポイント ジェネリックメソッドを利用しよう ジェネリックメソッドは型推論を行う ジェネリック static ファクトリーメソッド 型推論を利用したテクニック ただし、現代にいるならダイヤモンド演算子を使うべき ジェネリックシングルトンファクトリー それぞ…

【Effective Java】項目26:ジェネリック型を使用する

ジェネリック型を使う 今回は簡単にジェネリック型の使い方・書き方について説明します。 項目6での説明に利用したスタックの実装を、ジェネリックスを用いた実装に置き換えることを例としてみます。 ジェネリックスを利用しない元のスタック実装は以下の通…

【Effective Java】項目25:配列よりリストを選ぶ

ジェネリックスと配列 前回の記事 ではジェネリックス型の不変、共変、反変について説明しました。 今回はジェネリクス型のリスト(List<E>)と配列の性質の違いについて説明します。 前回も説明したように、Java のジェネリックス型は不変である一方、配列は共</e>…

【Effective Java】項目24:無検査警告を取り除く

今回は「項目24:無検査警告を取り除く」。 ポイント 無検査警告は必ず取り除く 方法1:コードを変更して警告を取り除く 方法2:注意して @SuppressWarnigns アノテーションで警告を抑制する ジェネリックスに対するコンパイル警告 ジェネリックスを利用…

【Effective Java】項目23:新たなコードで原型を使用しない

第5章から Effective Java シリーズ再開。第5章はジェネリックスについて。 今回は「項目23:新たなコードで原型を使用しない」。 ポイント ジェネリックスを積極的に使う 実行時ではなくコンパイル時にエラーをチェックできる 原型は利用しない 非境界…

【Effective Java】項目22:非 static のメンバークラスより static のメンバークラスを選ぶ

クラスの中に定義されたクラスを『ネストしたクラス』と呼ぶ。 ネストしたクラスは4種類に分類できるが、非 static メンバークラスよりも static メンバークラスを利用するべき。 ネストしたクラス ネストしたクラスには以下の4種類があり、static のメン…

【Effective Java】項目21:戦略を表現するために関数オブジェクトを利用する

戦略パターンを実現するため、関数オブジェクトを利用する。 関数オブジェクト 多くのプログラミング言語では、関数ポインタ、委譲、ラムダ式と呼ばれるような機構を利用して、関数自体の受け渡しが可能になっている。 関数自体をある関数に与えることで、呼…

【Effective Java】項目20:タグ付クラスよりクラス階層を選ぶ

クラスが2つ以上の特性を持っている場合、タグフィールドを保持するよりも、クラス階層を利用するべき。 タグ付クラス タグ付クラスとはクラスが2つ以上の特性を持っていて、タグフィールドを保持することで、それらを区別するように実装されているクラス…

【Effective Java】項目19:型を定義するためだけにインタフェースを利用する

インタフェースは、その実装クラスのインスタンスで何ができるかだけを述べるべきである。 その他の目的、たとえば定数インタフェースなどには利用しない。 定数インタフェース メソッドを持たず、static final の定数を外部に提供しているだけのインタフェ…

【Effective Java】項目18:抽象クラスよりインタフェースを選ぶ

Java では抽象クラスよりも、インタフェースを利用するべき。 抽象クラスとインタフェース 抽象クラスとインタフェースには以下の違いがある。 抽象クラスはメソッドの実装を含むことが許されるが、インタフェースは許されない 抽象クラスを実装するためには…

【Effective Java】項目17:継承のための設計および文書化する、でなければ継承を禁止する

継承させることを意図するクラスを作成するときは、継承のために設計し、文書化する。 そうでない場合には継承させないようにする。 自己利用(self-use)の文書化 クラスはオーバーライド可能なメソッドの自己利用を文書化する必要がある。 個々の public …

【Effective Java】項目16:継承よりコンポジションを選ぶ

継承よりもコンポジションを選ぶべきである。 継承の利用 継承はコードを再利用するための一般的な手法だが、常に最適なものとは限らない。 継承を安全に利用することができるのは以下の場合である。 スーパークラスもサブクラスも特定のパッケージ配下にあ…

【Effective Java】項目15:可変性を最小限にする

クラスの可変性は最小限にするべきである。 不変クラス 不変クラスとは、そのインスタンスを変更できないという性質をもつクラス。 インスタンスが生成された時点ですべての情報を持っていて、インスタンスの生存期間中はそれらの情報が変化しないことが保証…

【Effective Java】項目14:public のクラスでは、public のフィールドではなく、アクセッサーメソッドを使う

クラスがパッケージの外からアクセス可能ならば(public ならば)、ゲッターとセッターを提供するべき。 public なクラスがデータフィールドを公開すると、その内部的な表現を永久に変更できなくなる。 一方、クラスがパッケージプライベート・private のネ…

【Effective Java】項目13:クラスとメンバーへのアクセス可能性を最小限にする

ここから第4章「クラスとインターフェス」。 クラスとインタフェースは Java の中心に位置し、抽象化の基本となる要素。 この章では、クラス・インタフェースが利用可能で、頑強で、柔軟になるような指針を議論する。 最初の項目は情報隠蔽・カプセル化に関…

【Effective Java】項目12:Comparable の実装を検討する

Comparable インタフェースの compareTo を実装するとインスタンスが順序を持つようになる。 第3章で議論した他のメソッドとは異なり、compareTo メソッドは Object では宣言されていない。 ただし、Comparable を実装すると、多くの一般的なアルゴリズムや…

【Effective Java】項目11:clone を注意してオーバーライドする

本項目では正しく機能する clone メソッドを、どのように、いつ実装するかを議論する。 Cloneable インタフェース Cloneable インタフェースはオブジェクトが複製を許可していることを示す。 ただし、Cloneable インタフェース自体は空のインタフェースであ…

【Effective Java】項目10:toString を常にオーバーライドする

toString をオーバライドして意味のある文字列を返すようにする。 toString のオーバーライド java.lang.Object は toString() を実装しているが、ユーザーにとってよい情報を返すわけではない。 Object obj = new Object(); // 「クラス名@ハッシュコード値…

【Effective Java】項目9:equals をオーバーライドする時は、常に hashCode をオーバーライドする

equals をオーバーライドする時は、hashCode メソッドを必ずオーバーライドしなければならない。 オーバーライドしない場合、Object.hashCode の一般契約を破ることになり、HashMap、HashSet、HashTable など、hashCode の一般契約に基づくコレクションが適…

【Effective Java】項目8:equals をオーバーライドするときは一般契約に従う

第3章『すべてのオブジェクトに共通のメソッド』に入る。 第3章は、Object.equals()、Object.hashCode()、Object.toString()、Object.clone() について、いつ、どのようにオーバーライドするかを説明する。 finalize も同様のものだが、すでに項目7で議論…

【Effective Java】項目7:ファイナライザを避ける

Java のファイナライザは予想不可能で、危険であり、一般的には使う必要はない。 C++ プログラマは Java のファイナライザを C++ のデストラクタと対応付けて考えてしまいがちだが、それは大きな間違いである。 C++ のデストラクタはコンストラクタに対応す…

【Effective Java】項目6:廃れたオブジェクト参照を取り除く

メモリリークを回避するため廃れたオブジェクトの参照は取り除かなければならない。 C や C++ から、ガーベージコレクション(GC)を持つ言語に切り替えると、メモリ管理について考える必要がないように感じることがあるが、それは間違いだ。 次のスタック実…

【Effective Java】項目5:不必要なオブジェクトの生成を避ける

機能的に同じオブジェクトを、必要になるごとに再生成するのは避ける。 よくない例 極端にだめな例としては以下の様なコードがある。 // だめな例 String s = new String("stringee"); "stringee" 自身が String オブジェクトであり、String コンストラクタ…

【Effective Java】項目4:private のコンストラクタでインスタンス化不可能を強制する

static のメソッドと static なフィールドだけからなるクラスを書く場合は private コンストラクタでインスタンス化不可能をクライアントに強制するべきである。 static ユティリティクラス そのようなクラスは悪く評価されていることもあるが、java.lang.Ma…

【Effective Java】項目3:private のコンストラクタか enum 型でシングルトン特性を強制する

シングルトンは、手短にいえば厳密に一度しかインスタンスが生成されないクラス。 ただし、クラスをシングルトンにするとデメリットも多々あるため本当に必要な場合のみ行うこと。 伝統的なシングルトン実装 Java の リリース 1.5 より前はシングルトンを実…

【Effective Java】項目2:数多くのコンストラクタパラメータに直面した時にはビルダーを検討する

多くのオプションパラメータを持つオブジェクトを生成する場合はビルダーパターンを利用することを検討する。 テレスコーピングパターン 多くのオプションパラメータが存在するとき、伝統的にはテレスコーピングコンストラクタと呼ばれるパターンが利用され…

【Effective Java】項目1:コンストラクタの代わりに static ファクトリーメソッドを検討する

追記:2018年2月16日 Effective Java 3rd Edition を踏まえて内容をアップデートした記事を書きました。 こちらをご覧ください。 www.thekingsmuseum.info オブジェクトを生成するため、public コンストラクタの代わりに static ファクトリーメソッドを提供…

【Effective Java】第1章:はじめに

追記:2018年1月21日 Effective Java 3rd Edition を踏まえて内容をアップデートした記事を書きました。 こちらをご覧ください。 www.thekingsmuseum.info 第一章は前置き話がメイン。 第1章:はじめに この本の特徴は多くのデザインパターンとイディオムを…

(c) The King's Museum