Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Groovy Goodness: Create CopyWith Method with Immutable Annotation

DZone's Guide to

Groovy Goodness: Create CopyWith Method with Immutable Annotation

· Java Zone ·
Free Resource

Get the Edge with a Professional Java IDE. 30-day free trial.

For a long time we can annotate a class with the @Immutable AST transformation so only an immutable instance of a class can be created. Since Groovy 2.2 we can use the annotation parameter copyWith. If we set the value of this parameter to true the AST transformation generates a new method copyWith() in the class. The method returns a new immutable instance of the class. We can pass a map with property names and values we want to set in the newly created instance.

In the following sample code we create a new immutable class User and we use the @Immutable annotation and set the parameter copyWith to true:

import groovy.transform.Immutable

@Immutable(copyWith = true)
class User {
    String name
    String email
}

// Create immutable instance of User.
def mrhaki = new User('mrhaki', 'mrhaki@mrhaki.com')

mrhaki.with {
    assert name == 'mrhaki'
    assert email == 'mrhaki@mrhaki.com'
}

// Use new copyWith method to create a new immutable
// instance of the User class where name property
// is changed and email property is unchanged.
def hubert = mrhaki.copyWith(name: 'Hubert A. Klein Ikkink')

hubert.with {
    assert name == 'Hubert A. Klein Ikkink'
    assert email == 'mrhaki@mrhaki.com'
}

// The properties are still immutable:
try {
    hubert.email = 'new-mail@host.nl'
} catch (ReadOnlyPropertyException e) {
    assert 'Cannot set readonly property: email for class: User' == e.message
}

Code written with Groovy 2.2.

Get the Java IDE that understands code & makes developing enjoyable. Level up your code with IntelliJ IDEA. Download the free trial.

Topics:

Published at DZone with permission of

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}