Regarding an Immutable class defensive copying

半腔热情 提交于 2020-01-02 07:11:15

问题


I have a query regarding creating a Immutable class. Following are the points which I take in consideration:

  1. Make the class final
  2. Make all members final, set them explicitly, in a static block, or in the constructor
  3. Make all members private
  4. No Methods that modify state
  5. Be extremely careful to limit access to mutable member components(remember the field may be final but the object can still be mutable. ie private final Date imStillMutable) - See defensive copying or its cousin copy constructors for more info.


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?


回答1:


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.




回答2:


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.



来源:https://stackoverflow.com/questions/12000655/regarding-an-immutable-class-defensive-copying

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!