In Groovy, we can create immutable objects using the @Immutable annotation.
Immutable Objects
The annotation makes an immutable object.
1 2 3 4 5 6 7 8 9 | package com.turreta.groovy import groovy.transform.Immutable @Immutable class ImmutablePerson { String lastName; String firstName; } |
Immutable Annotation
To instantiate and initialize the object’s properties, use the constructor with named parameters.
1 | def iPerson = new ImmutablePerson(firstName: "John", lastName: "Doe") |
Testing with Immutable Objects
Let’s test out the class by instantiating it with values and modifying one of the properties.
1 2 3 4 5 6 7 8 9 10 11 12 13 | package com.turreta.groovy class Main { static void main(String[] args) { def iPerson = new ImmutablePerson(firstName: "John", lastName: "Doe") println iPerson.firstName println iPerson.lastName iPerson.firstName = "Jane" } } |
Line 11 throws a ReadOnlyPropertyException.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | Exception in thread "main" groovy.lang.ReadOnlyPropertyException: Cannot set readonly property: firstName for class: com.turreta.groovy.ImmutablePerson John at groovy.lang.MetaClassImpl.setProperty(MetaClassImpl.java:2749) Doe at groovy.lang.MetaClassImpl.setProperty(MetaClassImpl.java:3775) at com.turreta.groovy.ImmutablePerson.setProperty(ImmutablePerson.groovy) at org.codehaus.groovy.runtime.InvokerHelper.setProperty(InvokerHelper.java:197) at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.setProperty(ScriptBytecodeAdapter.java:484) at com.turreta.groovy.Main.main(Main.groovy:11) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147) |
References