我正在阅读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
可以通过构造函数b
与public Sample(int[] field1, Sample sampleForField2)
共享其内部。这会导致混叠,导致sample1
的{{1}}值为field2
。
因此,我的第二个问题是:实例之间共享可变的内部结构不会破坏不变性吗?
答案 0 :(得分:0)
如果您以不可变的方式公开对象的内部,则可以共享不可变对象的内部。
例如:
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));
}
}