Reputation: 269
I have a query regarding creating a Immutable class. Following are the points which I take in consideration:
But I did not understand the 5 point completely at all, could you please advise or show me a example in which the 5 point is clear in that example?
Upvotes: 3
Views: 1708
Reputation: 1500795
Point 5 suggests that any time you have any methods which would return something to do with a mutable object, you'd want to create a copy which is independent of the private state. For example:
public final class Foo
{
private final List<String> strings;
public Foo(List<String> strings)
{
// Defensive copy on construction. Protects from constructing
// code mutating the list.
this.strings = new ArrayList<String>(strings);
}
public List<String> getStrings()
{
// Defensive copy on read. Protects from clients mutating the list.
return new ArrayList<String>(strings);
}
}
Note that the defensive copying is only required when the state is mutable. For example, if you used an ImmutableList
(e.g. from Guava) as the state in the above class, you'd need to create a new list on construction (unless the input is also an ImmutableList
) but not in getStrings
.
Also note that in this case String
is immutable, so we don't need to copy each string. If this were a List<StringBuilder>
we'd need to create a new list and a new copy of each element as part of the defensive copy. As you can see, life becomes simpler when all your state is immutable too.
Upvotes: 5
Reputation: 47373
final
means that the pointer can't point to another reference.
For example:
final Object obj = new Object();
obj = new Object(); //Invalid
But final
doesn't prevent modifiying the object:
obj.setWhatever("aaa"); //Perfectly valid
If you haven't limited the access to the members, then anyone can get the object and modify it.
For example: yourClass.getObject().setWhatever("aaa").
Defensive copying means that getObject()
won't return directly the object, but it will make a copy of it and then return it. This way if the caller modifies the returned object, it won't modify the original member of the class.
Upvotes: 3