Meaning of “shallowly immutable” in the documentation of Record in Java 14

社会主义新天地 提交于 2021-02-17 21:10:56

问题


I am reading the documentation of Records and don't understand the term "shallowly immutable". What do we mean by shallowly immutable? And if it's immutable why we need a copy constructor? Why two "Hello Worlds!"?

For all record classes, the following invariant must hold: if a record R's components are c1, c2, ... cn, then if a record instance is copied as follows:

 R copy = new R(r.c1(), r.c2(), ..., r.cn());  // copy constructor ?

then it must be the case that r.equals(copy).


回答1:


Shallowly immutable means, that if a class has fields, these fields are treated as being final. However, their fields (i.e. the fields of the fields) don't need to be final.

You don't need to implement a constructor, it's already implemented this way for you. But if you choose to implement it yourself, e.g. for argument validation, then this invariant should hold.




回答2:


If you consider a class as a composite or hierarchy of other classes and primitives (ints, arrays, etc.), shallow immutability refers to the immutability (constant-ness) of just the first level.

It is in contrast to the term 'deep immutability', which refers to the immutability of the whole hierarchy. Most of the tangible benefits that you hear about immutability, such as implicit thread-safety, apply only to something which is deeply immutable.

Consider this class

class Foo {
    private final MutableBar bar;

    //ctor, getter
}

This class is shallowly immutable. It cannot be changed directly, but can be changed indirectly, for example

foo.getBar().setSomeProperty(5);

so it is not deeply immutable.

Another example of shallow immutability, using only primitives

class Foo {
    private final int[] ints;

    Foo(int[] ints) {
        this.ints = ints;
    }
}

This can be mutated like so

int[] ints = {1};
Foo foo = new Foo(ints);
ints[0] = 2;

For a small hierarchy, it is sometimes simple to make a shallowly immutable class deeply immutable. It usually involves defensive copies, or switching mutable classes to immutable variations.

class Foo {
    private final int[] ints; 

    Foo(int[] ints) {
        // copy to protect against the kind of mutation shown above
        this.ints = Arrays.copyOf(ints, ints.length);
    }

    // if you must have a getter for an array, make sure not to return the array itself, 
    // otherwise the caller can change it.
    // for performance reasons, consider an immutable List instead - no copy required
    int[] getInts() {
        return Arrays.copyOf(ints, ints.length);
    }
}


来源:https://stackoverflow.com/questions/62057172/meaning-of-shallowly-immutable-in-the-documentation-of-record-in-java-14

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