Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does @Immutable work in groovy?

Tags:

groovy

When I execute the below code in the groovy console, I get an groovy.lang.ReadOnlyPropertyException. Which is as expected as the property x should not be possible to change (as the ClassA is immutable).

import groovy.transform.Immutable
@Immutable class ClassA {
    int x
}

def a = new ClassA(x: 5);
a.x = 1

But if change the access modifier to private for the x variable, then I can execute this in the groovy console:

import groovy.transform.Immutable
@Immutable class ClassA {
    private int x
}

def a = new ClassA(x: 5);
a.x = 1
println(a.x)

Why is this? Why does the added private access modifier makes ClassA mutable?

like image 723
etxalpo Avatar asked Sep 02 '14 04:09

etxalpo


1 Answers

The docs have a clear stand on this. They always talk about "properties". There are also exerpts indicating, that "rolling your own" is not considered "state":

You don't have to follow Groovy's normal property conventions, e.g. you can create an explicit private field and then you can write explicit get and set methods. Such an approach, isn't currently prohibited (to give you some wiggle room to get around these conventions) but any fields created in this way are deemed not to be part of the significant state of the object and aren't factored into the equals or hashCode methods.

a trivial indicator for this is the fact, that toString is created for such classes. e.g.:

@groovy.transform.Immutable
class A {
    private int a
}

@groovy.transform.Immutable
class B {
    int b
}

a=new A()
a.a = 42
println a
b=new B()
// b.b = 42
println b

will print:

A()
B(0)

showing, that A.@a is not part of the "calculations" for immutability (the "significant state"). and as you can access private vars in groovy, your code above works just fine.

like image 72
cfrick Avatar answered Oct 16 '22 17:10

cfrick