[英]Why is sharing the mutable internals of immutable objects a good idea?
我正在阅读Joshua Bloch的“有效Java”,并且有两个问题。 Bloch陈述以下内容。
您不仅可以共享不可变的对象,而且可以共享其内部。
他然后前进到得到具有的一个实例的示例BigInteger
与另一个共享其大小阵列BigInteger
实例。 我的第一个问题是:这是否违反了Bloch先前提出的规则,即
确保以独占方式访问可变组件。
作为共享可变内部结构可能有问题的一个示例,在我看来,如果同一类的两个实例sample1
和sample2
可以共享其内部结构,那么您可以得到以下内容。
public final class Sample {
private final int[] field1;
private final int[] field2;
public Sample(int[] field1, int[] field2) {
this.field1 = field2;
this.field2 = field2;
}
public Sample(int[] field1, Sample sampleForField2) {
this.field1 = field1;
for (int i = 0; i < sampleForField2.field2.length; i++) {
sampleForField2.field2[i] += 1;
}
this.field2 = sampleForField2.field2;
}
public static void main(String[] args) {
Sample sample1 = new Sample(new int[]{0, 1}, new int[]{10, 11});
Sample sample2 = new Sample(new int[]{20, 21}, sample1);
System.out.println(Arrays.toString(sample1.field2));
}
}
在上面的示例中, a
可以通过构造函数public Sample(int[] field1, Sample sampleForField2)
与b
共享其内部。 这导致混叠,导致sample1
的field2
值为{11, 12}
。
因此,我的第二个问题是:实例之间共享可变的内部结构不会破坏不变性吗?
如果您以不可变的方式公开对象的内部,则可以共享一个不可变对象的内部。
例如:
public class ImmutableObj {
private final String[] internals;
public ImmutableObj(String[] strings) {
internals = Arrays.copyOf(strings, strings.length);
}
public String[] getInternals() {
// return a copy of the internal state, since arrays
// do not offer an immutable view
return Arrays.copyOf(internals, internals.length);
}
}
数组是一个效率低下的示例,但仍有可能。 更高效的方法是将内部状态存储/公开为某种Collection<String>
因此您可以将内部设置为不可修改的对象,开始于:
public class ImmutableObj {
// Simply make this public instead of getter since it is read-only
public final List<String> internals;
public ImmutableObj(String[] strings) {
internals = Collections.unmodifiableList(Arrays.asList(strings));
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.