Effective Java with Groovy - Immutability
It would seem like mutability is the default design approach when it comes to Java. However, reading "Effective Java" makes you change your mind. The book suggests - 'minimise mutability'. Also, what is highly useful is the reason for favouring immutability - "immutability is simple". Did you get surprised?
Now, let's seek an answer to why many developers don't favour immutability. In Java, you have to write additional code to make objects immutable. You would start by making the fields final. This act would also imply that the fields cannot have setter methods. Hence you are only left with the constructors to initialise the fields. The challenge here is if your constructor has several arguments, its hard to remember the order of fields, especially when many of them share the same type.
Groovy reduces the cost of making objects immutable by providing higher-level constructs.
If you are new to Groovy, you might want to get a taste of Groovy from this post.
Consider the following code.
import groovy.transform.Immutable
@Immutable
class Rectangle {
int length
int breadth
}
Here I have applied the groovy.transform.Immutable
AST transformation. This AST transformation will have the following influence on the compiler-generated class.
- The fields
length
andbreadth
are declared final (They are already private even without the@Immutable
AST transformation. - A constructor with both
length
andbreadth
as arguments gets created. Also, the compiler generates a constructor which takes ajava.util.Map
type as an argument so that you can instantiate the class with fewer fields and leave the rest with their default values. - No setter methods get generated (they would have been present in the absence of
Immutable
AST transformation). - Also
equals
andhashCode
methods are generated for you, without explicitly specifyingEqualsAndHashCode
AST transformation. toString
method is implemented for you.
Let's create an instance of the class as follows.
Rectangle rectangle = new Rectangle(breadth: 10, length: 20)
println rectangle // Rectangle(20, 10)
Thus Groovy solves reduces the barrier to favour immutability in the following ways.
- No boilerplate code. All you have to do is apply the
Immutable
AST transformation on the class. - You don't need to remember the order or fields to invoke the constructor. Instead, make use of the map constructor.
If you are interested in learning more about how Effective Java applies to Groovy code, you may want to take a look at my GR8Conf EU presentation or
To learn more about Effective Java with Groovy, refer to the collection of posts here.
References: