Different between immutable and effectively immutable objects?

后端 未结 4 917
粉色の甜心
粉色の甜心 2021-02-04 02:23

This is a sentence from Java Concurrency in Practice

Shared read-only objects include immutable and effectively immutable objects.

4条回答
  •  悲&欢浪女
    2021-02-04 02:54

    Here's my understanding from a bit of googling and finding this article. An Effectively Immutable Object is an object that contains fields that can be mutated, but it doesn't let anything mutate those fields because it never gives you a reference to them. For example, lets say you create a class with an ArrayList in it. ArrayLists are mutable, but if your class always returns a copy of the ArrayList and everything else in your class is immutable, then your class has become effectively immutable: There's no way to mutate the state of an instance of your class.

    The blog post gives this as an example of an effectively immutable class:

    import java.awt.*;
    
    public class Line {
    
       private final Point start;
       private final Point end;
    
       public Line(final Point start, final Point end) {
           this.start = new Point(start);
           this.end = new Point(end);
       }
    
       public void draw() {
           //...
       }
    
       public Point getStart() {
           return new Point(start);
       }
    
       public Point getEnd() {
           return new Point(end);
       }
    }
    

    Point objects are mutable, but that's ok, because this class does not give anyone the direct reference to it's Point instances. Instead, it returns a new instance with the same value in it. That way, nobody can mutate the state of the Line class. This makes the Line class effectively immutable.

    So how is this different from a truly immutable class? A truly immutable class has fields that are also immutable. Lets imagine Line was truly immutable. To do that we're also going to have to imagine that Point is immutable. Making these assumptions, the getStart() method could have been able to be written like this:

    public Point getStart() {
       return start;
    }
    

提交回复
热议问题