Effective java 輪読会 第2章 項目1,2,3,4

Post on 18-Dec-2014

807 views 3 download

description

 

Transcript of Effective java 輪読会 第2章 項目1,2,3,4

Effective Java 輪読会

2013/11/27開発部 田中

第2章 オブジェクトの生成と消滅(前半)

• 項目1– コンストラクタの代わりに static ファクトリー

メソッドを検討する

メリット

名前を付けられる• 可読性の向上– クラスから生成されるインスタンスが特殊な

場合Ex. BigInteger.probablePrime

– 同じシグニチャを持つ複数のコンストラクタを定義する場合

インスタンスの生成は強制でない

• static フィールドを返すEx. Boolean.valueOf(boolean)

• 「シングルトン」、「インスタンス化不可能」であることを保証できる

Cf. 「インスタンス制御」されている → 項目3、項目4、項目15

サブタイプのオブジェクトを返せる

• ユーティリティクラスに、戻り値がインターフェースであるメソッドを定義する– 実際の戻り値のクラスを Public で定義する必

要がなくなる(実装クラスを隠蔽)

型パラメータの冗長さを低減

Map<String, List<String>> map = new HashMap<String, List<String>>();

public static <K, V> HashMap<K, V> newInstance() { return new HashMap<K, V>();}

Map<String, List<String>> map = HashMap.newInstance();

デメリット

サブクラスを作れない(?)• 意図してインスタンス化不可能にする– コンストラクタを private にする

他の static メソッドと区別がつかない

• 命名規約で回避• valueOf()• getInstance()• newInstance()

まとめ• インスタンス化の方法として、状況に応じ

て static ファクトリーメソッドを用いるべきである

• 項目2– 数多くのコンストラクタパラメータに直面し

た時にはビルダーを検討する

テレスコーピングコンストラクタ

• 必須フィールドとオプションフィールド– 必須フィールドのコンストラクタに、オプ

ションフィールドのコンストラクタを1つずつ追加する

→  使いづらく、読みにくい

JavaBeans

• パラメータなしのコンストラクタで初期化した後、セッターでフィールドに値をセットしていく

→  不整合な状態になるかもしれない→   final フィールドにできない

ビルダー

• build() で目的のクラスのインスタンスを生成

• 目的のクラスのフィールドは全てに final属性を付与できる

• 読みやすい(宣言的?)

NutritionFacts cocaCola = new NutritionFacts.Builder(240, 8). calories(100).sodium(35).build();

まとめ• 多くのパラメータを持つクラスの初期化

方法としてビルダーパターンは有効である• ただし、ビルダーを生成するコストが問

題になる可能性がある

• 項目3– private のコンストラクタか enum 型でシング

ルトン特性を強制する

クラスをシングルトンにする方法

public final フィールド

• コンストラクタを private にすることで、オブジェクトの生成を 1 回のみに強制する

public class Elvis { public static final Elvis INSTANCE = new Elvis(); private Elvis() { ... }

...}

static ファクトリーメソッド

• インスタンスは private static final フィールドで一度のみ初期化

• ファクトリーメソッドで参照するINSTANCE は常に同一インスタンス

public class Elvis { private static final Elvis INSTANCE = new Elvis(); private Elvis(); public static Elvis getInstance() { return INSTANCE; }

...}

単一要素の enum 型public enum Elvis { INSTANCE;

...}

• 項目4– private のコンストラクタでインスタンス化不

可能を強制する

private コンストラクタ

• デフォルトコンストラクタを抑制• サブクラス化も不可能

public class UtilityClass {

private UtilityClass() { throw new AssertionError(); }

...}