如果将某个类视为其他类和基元(整数、数组等)的复合或层次结构,则浅层不可变性仅指第一级的不可变性(常量)。
它与术语“深度不变性”相反,后者指的是整个层次结构的不变性。您听到的有关不可变性的大多数有形好处(例如隐式线程安全)仅适用于非常不可变的东西。
考虑此类
class Foo {
private final MutableBar bar;
//ctor, getter
}
此类是浅不可变的。它不能直接更改,但可以间接更改,例如
foo.getBar().setSomeProperty(5);
所以它不是非常不可变的。
浅层不可变性的另一个示例,仅使用基元
class Foo {
private final int[] ints;
Foo(int[] ints) {
this.ints = ints;
}
}
这可以像这样变异
int[] ints = {1};
Foo foo = new Foo(ints);
ints[0] = 2;
对于一个小层次结构,有时很容易使浅不可变类深度不可变。它通常涉及防御性副本,或将可变类切换到不可变变体。
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);
}
}