java:イミュータブルなクラスを作る方法

「イミュータブル」とは「不変」という意味で、オブジェクト指向の世界では「状態(クラス変数)がオブジェクト生成時から変更されないこと」を指します。
有名所では、Stringがイミュータブルなクラスとして知られています。

イミュータブルなクラスを自作するためには、以下の条件を満たすようにクラスを作成する必要があります。

①クラス変数はprivateで定義する

クラス変数が外のクラスから直接書き換えられるのを防ぐため

②setterメソッドを定義しない

クラス変数を書き換えるメソッドは定義しない

③クラスをfinalで定義する

サブクラスでクラス変数を書き換えられるのを防ぐため

④ミュータブルなオブジェクトへの参照を含んでいない

ミュータブルなオブジェクトを変更する処理を記述しないようにするため

クラスをイミュータブルにするメリットとしては、内部の状態の変化を気にする必要が無くなるために処理を追いやすくなるというのがあります。
関数型プログラミングにも通じる考え方なのですが、オブジェクト生成より後で内部の状態が書き変わることがないため、クラスのメソッドが返す値が一定となり、内部の状態の変化を気にしながらトレースする必要がなくなります。
また、
hoge2 = hoge1;
のようなオブジェクトのアドレスのコピーが使いやすくなります。
イミュータブルではないクラスでこのコピー方法を用いると、hoge2の状態の変化がhoge1にも影響してしまい(hoge1とhoge2で同じアドレスを指しているため)、思わぬ影響が出ることがあります。
しかし、イミュータブルなクラスであれば、状態を変化させようと思えば新たにオブジェクトを作り直して新たなメモリ領域を確保しなければならないので、hoge2の状態を変化させても(オブジェクトを作り直しても)hoge1へ影響するのを防ぐことができます。
イミュータブルではないクラスでも、オブジェクトの中身全体をコピーすれば思わぬ影響を防ぐことはできるのですが、オブジェクトのアドレスをコピーする場合と比べてメモリ使用量が増え処理も遅くなります。

以下で、イミュータブルなクラスを定義してそれを使用するサンプルコードを示します。

【サンプルコード】

・ImmutableCalc.java

・ImmutableTestMain.java

【実行結果】


いかがでしたでしょうか。

オブジェクトの内部の状態を意識する手法には多くの技術者が慣れ親しんでいると思いますし、オブジェクトのアドレスのコピーも便利ですが、それが思わぬ影響を及ぼすこともあります。
思わぬ影響を防ぐために、イミュータブルなクラスを作成する手法は覚えておいて損はないでしょう。

これからも役に立つ情報を発信していきたいと思います!

カテゴリーjava

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

CAPTCHA