9

我一直在阅读《Effective Java》,我发现你不仅可以共享不可变对象,还可以共享它们的内部。但是,我很难弄清楚这到底意味着什么,一个例子肯定会有所帮助,因为书中没有给出例子。我已经知道不可变对象无法更改,例如String.

4

4 回答 4

9

进一步阅读本书

该类BigInteger在内部使用符号幅度表示。符号由 an 表示,int幅度由int数组表示。该negate方法产生一个新BigInteger的大小相似但符号相反的信号。它不需要复制数组;新创建的BigInteger指向与原始相同的内部数组。

于 2013-06-27T07:29:17.947 回答
6

例如,如果你有一堂课

public class Vector2d { 
  private final BigDecimal a;
  private final BigDecimal b;
}

然后是那个类的“内部” ab由于这是它们的实例,BigDecimal因此它们是不可变的。如果您实现这样的操作,setBToZero()您可以简单地重用您的实例,a而不必重新创建一个新实例。例如

public Vector2d setBToZero() { 
  return new Vector2d(a, 0);
}

你分享你的内部a,因为它是不可变的,你不必担心你的共享状态的变化。当涉及到大型对象时,这尤其有用。如果您使用接口,则只能通过使用代理对象来实现某些操作。

于 2013-06-27T07:34:40.620 回答
0

我认为他们真正想说的是,通常对于可变对象,您可以使用 getter 和 setter 方法访问和修改字段,并在多线程环境中同步这些字段。但是,使用不可变对象,因为这些字段可以保证始终相同,您可以完全安全地制作它们public并“公开”和“共享”它们。这很好——访问公共字段比调用方法更清晰、更有效。

于 2013-06-27T07:30:15.340 回答
0

共享不可变对象内部的示例。Data 是不可变的,它与 Data 的其他不可变实例共享其字节数组。

public final class Data {

    private byte[] data; 
    private int start;
    private int end;

    private Data(byte[] data, int start, int end) {
        this.data = data;
        this.start = start;
        this.end = end;
    }

    public Data(byte[] data) {
        this(Arrays.copyOf(data), 0, data.length - 1); // copy so nobody can access our array
    }

    public Data lowerHalf() {
        return new Data(this.data, 0, data.length / 2);  // sharing byte array
    }

    public byte get(int index) {
        return data[start + index];
    }         
}        
于 2013-06-27T07:35:33.367 回答