@ImmutableアノテーションをクラスにつけてあげるとImmutableなクラスが実現できる。
※Immutableアノテーションは、groovy.langパッケージにもあるけど、非推奨になっているのでgroovy.transformの方をしようする。
Immutableなクラスの例
import groovy.transform.Immutable
@Immutable
class Hoge {
String hoge
int num
}
Immutableなクラスを変更しようとするとどうなるか?
Hogeクラスをインスタンス化し、hogeプロパティを変更してみます。
def hoge = new Hoge(hoge: "hoge", num: 100)
hoge.hoge = "変更"
実行してみると、ReadOnlyPropertyExceptionが発生し、クラスの状態が変更できないことがわかります。
Caught: groovy.lang.ReadOnlyPropertyException: Cannot set readonly property: hoge for class: goovy.immutable.Hoge
groovy.lang.ReadOnlyPropertyException: Cannot set readonly property: hoge for class: goovy.immutable.Hoge
at goovy.immutable.Hoge.setProperty(Hoge.groovy)
at goovy.immutable.main.run(main.groovy:6)
==演算子
Immutableなクラスにしてあげると、「==」演算子をオーバライドしてくれます。
お試しコード。
def hoge = new Hoge(hoge: "hoge", num: 100)
// immutableなオブジェクトは、「==」をオーバライドしてくれるから、
// 同じあたいかどうかになる
assert hoge == new Hoge(hoge: "hoge", num: 100)
assert hoge != new Hoge(hoge: "hoge", num: 101)
def mutableHoge = new MutableHoge(hoge: "hoge", num : 100)
// mutableなオブジェクトは、==がオーバライドされないので同一インスタンスかの比較
assert mutableHoge != new MutableHoge(hoge: "hoge", num : 100)
ImmutableだとtoStringまで実装される
Immutableなクラスだと、toStringまで追加されるようです。
Immutableでないと、「hoge = goovy.immutable.Hoge@6c0089ab」な感じになりますが、Immutableだと「hoge = goovy.immutable.Hoge(hoge:hoge, num:100)」なります。