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
lengthandbreadthare declared final (They are already private even without the@ImmutableAST transformation. - A constructor with both
lengthandbreadthas arguments gets created. Also, the compiler generates a constructor which takes ajava.util.Maptype 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
ImmutableAST transformation). - Also
equalsandhashCodemethods are generated for you, without explicitly specifyingEqualsAndHashCodeAST transformation. toStringmethod 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
ImmutableAST 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: