为什么共享不可变对象的可变内部是个好主意?

我正在阅读 Joshua Bloch 的“Effective Java”并有两个问题。布洛赫陈述如下。


您不仅可以共享不可变对象,还可以共享它们的内部。


然后他继续举一个例子,其中一个实例BigInteger与另一个实例共享其幅度数组BigInteger。我的第一个问题是:这是否违反了布洛赫之前提出的规则,即


确保对可变组件的独占访问。


作为共享可变内部可能存在问题的一个示例,在我看来,如果同一个类的两个实例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'field2值为{11, 12}。


因此,我的第二个问题是:在实例之间共享可变内部不会破坏不变性吗?


蝴蝶不菲
浏览 151回答 1
1回答

慕姐8265434

只要您以不可变的方式公开对象的内部,就可以共享不可变对象的内部。例如:public class ImmutableObj {&nbsp; private final String[] internals;&nbsp; public ImmutableObj(String[] strings) {&nbsp; &nbsp; internals = Arrays.copyOf(strings, strings.length);&nbsp; }&nbsp; public String[] getInternals() {&nbsp; &nbsp; // return a copy of the internal state, since arrays&nbsp; &nbsp; // do not offer an immutable view&nbsp; &nbsp; return Arrays.copyOf(internals, internals.length);&nbsp; }}数组是一个低效的例子,但它仍然是可能的。更高效的事情是将内部状态存储/公开为某种形式,Collection<String>以便您可以将内部设置为不可修改的对象:public class ImmutableObj {&nbsp; // Simply make this public instead of getter since it is read-only&nbsp; public final List<String> internals;&nbsp; public ImmutableObj(String[] strings) {&nbsp; &nbsp; internals = Collections.unmodifiableList(Arrays.asList(strings));&nbsp; }}
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java