我一直在阅读Effective Java,并且我发现这样的声明:您不仅可以共享不可变对象,还可以共享其内部。但是,我正在努力弄清楚真正意味着什么,并且一个例子肯定会有所帮助,因为书中没有给出任何例子。我已经知道无法更改不可变对象,例如String
。
答案 0 :(得分:9)
进一步阅读book:
BigInteger
类在内部使用符号幅度表示。符号由int
表示,幅度由int
数组表示。negate
方法生成一个类似幅度和符号相反的新BigInteger
。 不需要复制数组;新创建的BigInteger
指向与原始内容相同的内部数组。
答案 1 :(得分:6)
例如,如果你有一个班级
public class Vector2d {
private final BigDecimal a;
private final BigDecimal b;
}
然后a
和b
是该类的“内部”。由于这是BigDecimal
的实例,因此它们是不可变的。如果您实施setBToZero()
之类的操作,则只需重复使用a
的实例,而无需重新创建新实例。例如
public Vector2d setBToZero() {
return new Vector2d(a, 0);
}
您共享内部a
,因为它是不可变的,您不必担心共享状态的更改。当涉及到大型物体时,这尤其有用。如果使用接口,则只能使用代理对象来实现某些操作。
答案 2 :(得分:0)
我认为他们真正说的是通常使用可变对象,您可以使用getter和setter方法访问和修改字段,并在多线程环境中同步这些字段。但是,对于不可变对象,因为这些字段始终保持一致,所以您可以完全安全地使它们public
和“暴露”并“共享”它们。哪个好 - 访问公共字段比调用方法更清晰,更有效。
答案 3 :(得分:0)
共享不可变对象内部的示例。数据是不可变的,它与其他不可变的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];
}
}