为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

蝴蝶不菲 2022-06-15 14:38:03
我正在阅读 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}。因此,我的第二个问题是:在实例之间共享可变内部不会破坏不变性吗?
查看完整描述

1 回答

?
慕姐8265434

TA贡献1813条经验 获得超2个赞

只要您以不可变的方式公开对象的内部,就可以共享不可变对象的内部。


例如:


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));

  }


}


查看完整回答
反对 回复 2022-06-15
  • 1 回答
  • 0 关注
  • 149 浏览

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号