Reputation: 6748
Recently on the interview I had an interesting question. We have mutable class:
final class Example {
private int i;
private String s;
private Object o;
// get, set
}
And instance of this class Example e = new Example();
Can we somehow make this instance immutable? Without changing original class.
My thoughts:
Upvotes: 0
Views: 118
Reputation: 129217
If you are unable to make modifications to the Example
class and you cannot subclass it (in your snippet, it is marked as final
) the closest solution I can think of is to create a wrapper class, which is immutable. This is not a perfect solution, and has it's drawbacks.
First, how to do it:
final class ImmutableExample {
// Redeclare every field as in the Example class
// but make sure they can't be reassigned
// (in this case I'll declare them as final)
private final int i;
private final String s;
private final Object o;
ImmutableExample(Example mutableExample) {
// copy fields from original
this.i = mutableExample.getI();
this.s = mutableExample.getS();
this.o = mutableExample.getO();
}
// add getters but definitely no setters
}
Then everywhere you have code like this:
Example e = new Example();
e.setI(42); // etc
Change to:
Example e = new Example();
e.setI(42); // etc
ImmutableExample immutableE = new ImmutableExample(e);
And pass around references to immutableE
, and make sure that the e
reference does not escape.
Now, for the drawbacks:
ImmutableExample
is not an instance of Example
, so you cannot pass the immutable type to a method which expects the mutable type, and operations like if (immutableE instanceof Example)
or (Example)immutableE
will not work as before
You have to be very careful that every field of Example
is also immutable, or ImmutableExample
will also be mutable. Consider, for example, that the field of type Object
could be something mutable, like a HashMap
or a Date
.
When the Example
class changes, you have to repeat the change in ImmutableExample
.
If it was possible to subclass Example
, or if it was an interface, this approach might be more useful, but I can't see any other way when Example
cannot be subclassed.
Upvotes: 2
Reputation: 5558
Immutability is a property of a class not an instance. So besides bytecode twiddling or other means to change the class; not possible.
With a none final class i would create an immutable decorator. That would not make the instance immutable, but provide an immutable wrapper to that instance.
You could not assign the instance to any variable/field, making it impossible to change it ;)
Upvotes: 0
Reputation: 43078
If each of those fields have getters/setters, then to make it immutable, you will have to
private
and final
Upvotes: 0