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?
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With