gpt4 book ai didi

java - 我是否总是需要克隆一个对象以确保 Java 中的封装?

转载 作者:行者123 更新时间:2023-12-02 09:32:33 24 4
gpt4 key购买 nike

给定一个 Outer 类,它将对 Inner 类的对象的引用作为参数:

public class Outer {

private Inner inner;

public Outer(Inner inner) {
// fails
// this.inner = inner;

// passes
this.inner = this.clone(inner);
}

public Inner getInner() {
return this.inner;
}

private Inner clone(Inner inner) {
return new Inner(inner.getInnerValue());
}
}

和只有整数值的Inner

public class Inner {

private int innerValue;

public Inner(int innerValue) { this.innerValue = innerValue; }

public void setInnerValue(int innerValue) {
this.innerValue = innerValue;
}

public int getInnerValue() {
return this.innerValue;
}
}

测试

class OuterTest {
@Test
void testEncapsulation() {
Inner inner = new Inner(3);
Outer outer = new Outer(inner);
inner.setInnerValue(4);
assertEquals(3, outer.getInner().getInnerValue());
}
}

仅当我克隆内部时才通过(请参阅注释失败)。一般情况下是这样吗?那么,每当我传递一个引用时,我都需要克隆每个引用吗?

最佳答案

不,并不总是。

另一种方法是让所有 setter 都为 Inner返回 Inner 的新实例,而不是设置 this 字段。通常这些 setter 将具有名称“+”,例如 withInnerValue :

public Inner withInnerValue(int innerValue) {
return new Inner(innerValue);
}

然后在测试中,您将被迫这样做:

void testEncapsulation() {
Inner inner = new Inner(3);
Outer outer = new Outer(inner);
inner = inner.withInnerValue(4); <---- this is forced to change
assertEquals(3, outer.getInner().getInnerValue());
}

通过重写Inner的 setter ,您已将其设为不可变,也就是说,一旦创建实例,其字段就无法更改。

关于java - 我是否总是需要克隆一个对象以确保 Java 中的封装?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57832763/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com