我正在阅读以下文件 记录并不理解 "浅尝辄止 "这个词。什么叫 浅尝辄止? 如果它是不可变的,为什么我们需要一个复制构造函数?为什么要有两个 "Hello Worlds!"?
对于所有的记录类,以下的不变性必须成立:如果一个记录R的成分是c1,c2,......cn,那么如果一个记录实例被复制成如下的样子。
R copy = new R(r.c1(), r.c2(), ..., r.cn()); // copy constructor ?
那么一定是这样的情况: r.equals(copy)
.
Shallowly immutable的意思是,如果一个类有字段,这些字段就会被看作是: final
. 然而, 其 字段(即字段的字段)不需要是 final
.
你不需要实现一个构造函数,它已经为你实现了。但是如果你选择自己实现它,例如为了参数验证,那么这个不变性应该成立。
如果你把一个类看作是其他类和基元(ints、数组等)的复合体或层次结构,那么浅层不变性指的是仅仅是第一层的不变性(不变性)。
它与 "深层不变性 "一词相反,后者指的是整个层次结构的不变性。你所听到的关于不可变性的大多数有形的好处,比如隐含的线程安全,只适用于深不可变的东西。
考虑一下这个类
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);
}
}