Effective Java(項目13)

うーん、進まない。カメ以下の歩み。ってか重たい(オレにとっては)項目が続いてる模様です。もっとさらっと流す程度でも良いのかも。
あとはてな記法を少し思い出したので使ってみた。ただ、手元のメモとしては逆に見づらくなるからどうしたもんかと思ったけどそれを一発で変換するスクリプトとか書けばいいんですかああそうですか。

○項目13 不変性を選ぶ

  • 不変であるクラス(不変クラス)のメリットはけっこうありますよ、という話

  • クラスが不変であるための条件5つ
    • オブジェクトを修正するためのいかなるメソッド(mutator(一般的にsetter))も提供しない
    • どのメソッドもオーバーライドされないことを保証する
    • すべてのフィールドをfinalにする
    • すべてのフィールドをprivateにする
    • 可変コンポーネントに対する独占的アクセスを保証する

  • 不変オブジェクトは単純である、オブジェクトが作られたときの状態を維持しつづける

→本質的にスレッドセーフ、同期不要となる

  • 不変クラスに対して、cloneメソッドやコピーコンストラクタを提供する必要がない(提供すべきでない)

→Javaプラットフォームの初期の頃はこのことが充分に理解されていなかったので、Stringクラスはコピーコンストラクタを持っていたりする

  • 不変クラスの欠点は、個々の異なる値に対して別々のオブジェクトを必要とすること

→オブジェクトが大きい場合はコストが高い(例えば1ビットしか違わない100万ビット長のBigInteger・・・とか)

  • クラスを不変にする方法はいくつかある
    • クラスをfinalにする
    • クラスの各メソッドをfinalにする
    • クラスのコンストラクタをprivateあるいはパッケージプライベートとし、代わりにpublicのstaticファクトリーを提供する

→3番目が多くの場合最善、staticファクトリーは便利

  • 最初に出てきたクラスが不変であるための5つの条件は実は必要以上に厳しかったり

→外部に分からない変更であれば、それは不変であることと同義となる
→事実多くの不変クラスはコストの高い計算結果をキャッシュする為のfinalでない冗長なフィールドを1つは持っている

  • 「全てのgetメソッドに対してsetメソッドを書きたい衝動に抵抗してください」とあって感動した

→可変にすべき正当な理由がない限り、クラスは不変であるべき、そうでなければその可変性を可能な限り制限すべき

    • コンストラクタは全ての不変式が確率した完全に初期化された状態でオブジェクトを生成する
    • 部分的に生成されたインスタンスを他のメソッドへ渡すべきではない
    • コンストラクタとは別のpublicの初期化メソッドを提供すべきではない
    • あたかもオブジェクトが初期状態で生成されたかのように振舞う「最初期化」メソッドを提供すべきではない