Deb*_*was 26 java java-14 java-record
我正在阅读Records的文档, 但不理解“浅不可变”一词。我们所说的浅不可变是什么意思?如果它是不可变的,为什么我们需要一个复制构造函数?为什么有两个“Hello World!”?
对于所有记录类,以下不变量必须成立:如果记录 R 的组件是 c1、c2、... cn,那么如果记录实例被复制如下:
R copy = new R(r.c1(), r.c2(), ..., r.cn()); // copy constructor ?
Run Code Online (Sandbox Code Playgroud)
那么一定是这样的r.equals(copy)。
Ale*_*x R 30
浅不可变意味着,如果一个类有字段,则这些字段被视为final。但是,它们的字段(即字段的字段)不需要是final.
您不需要实现构造函数,它已经为您实现了这种方式。但是如果您选择自己实现它,例如用于参数验证,那么这个不变量应该成立。
Mic*_*ael 14
如果您将类视为其他类和基元(整数、数组等)的组合或层次结构,浅层不变性是指仅第一级的不变性(恒定性)。
它与术语“深度不变性”形成对比,后者指的是整个层次结构的不变性。你听到的关于不变性的大多数有形好处,比如隐式线程安全,只适用于非常不可变的东西。
考虑这个类
class Foo {
private final MutableBar bar;
//ctor, getter
}
Run Code Online (Sandbox Code Playgroud)
这个类是浅不可变的。不能直接改变,但可以间接改变,例如
foo.getBar().setSomeProperty(5);
Run Code Online (Sandbox Code Playgroud)
所以它并不是一成不变的。
另一个浅不变性的例子,只使用原语
class Foo {
private final int[] ints;
Foo(int[] ints) {
this.ints = ints;
}
}
Run Code Online (Sandbox Code Playgroud)
这可以像这样变异
int[] ints = {1};
Foo foo = new Foo(ints);
ints[0] = 2;
Run Code Online (Sandbox Code Playgroud)
对于一个小的层次结构,有时很容易使浅不可变的类深不可变。它通常涉及防御性副本,或将可变类切换为不可变变体。
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);
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1565 次 |
| 最近记录: |