Regarding defensive copying an immutable class

I have a request regarding creating an Immutable class. The following are points that I take into account:

  • Make the final class
  • Make all participants final, set them explicitly, in a static block or in a constructor
  • Make all members private
  • There are no methods that change state
  • Be extremely careful to limit access to mutable member components (remember that a field can be final, but an object can still be changed, i.e. a closed final Date imStillMutable). See protective copy or its cousin copy constructors for more information.


But I didn’t understand 5 points at all, could you advise or show me an example in which in this example it’s clear that there are 5 points?

+3
java immutability
Aug 17 '12 at 6:14
source share
2 answers

Clause 5 assumes that at any time when you have any methods that return something that needs to be done with a mutable object, you must create a copy that 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); } } 

Please note that protective copying is only required when the state is changed. For example, if you used an ImmutableList (e.g. from Guava) as the state in the above class, you would need to create a new list in the construct (unless the input is an ImmutableList ), but not in getStrings .

Also note that in this case, String is immutable, so we do not need to copy each line. If it was a List<StringBuilder> , we would need to create a new list and a new copy of each item as part of the protective copy. As you can see, life becomes easier when all your condition is also unchanged.

+5
Aug 17 '12 at 6:21
source share

final means the pointer cannot point to another link. For example:

 final Object obj = new Object(); obj = new Object(); //Invalid 

But final does not prevent the modification of the object:

 obj.setWhatever("aaa"); //Perfectly valid 

If you have not restricted access to members, everyone can get the object and modify it.

For example: yourClass.getObject().setWhatever("aaa").

Defensive copying means that getObject() will not directly return the object, but it will make a copy and then return it. Thus, if the caller modifies the returned object, it will not modify the original member of the class.

+3
Aug 17 '12 at 6:17
source share



All Articles