Create DEEP immutable object in runtime

Viewed 1372

I need to create immutable copy of an object in runtime with Java. I made use of org.springframework.cglib.beans.ImmutableBean, which can create immutable copy of an object using CGLIB.

But the problem is that it provides "first-level" immutability: it disallows change of an input object's properties, but it allows to change inner objects (e.g. get collection and add an element to it or get inner object and modify it's parameters etc.)

So the question is: what's the correct way of creating deep (recursive) immutable copy of an object so that one can't change inner objects also (at any level of nesting)?

2 Answers

You can use ImmutableProxy of the reflection-util library.

Example:

public class Inner
{
    private String data = "hello";
    // getters and setters
}
public class Outer
{
    private List<Inner> list = Arrays.asList(new Inner());
    // getters and setters
}
Outer outerImmutable = ImmutableProxy.create(new Outer());
Inner firstElement = outerImmutable.getList().get(0)

// this is initial state
assertThat(firstElement.getData()).isEqualTo("hello");

// throws UnsupportedOperationException
outerImmutable.setList(…);

// throws UnsupportedOperationException
firstElement.setData("bye!");
Related