基于值的类混乱

2024-05-23

我正在寻求一些澄清基于值的类的定义 https://docs.oracle.com/javase/8/docs/api/java/lang/doc-files/ValueBased.html。我无法想象,最后一个要点(6)应该如何与第一个要点一起使用

  • (1) 它们是最终的且不可变的 (尽管可能包含对可变对象的引用)
  • (6) 他们是可自由替换当相等时,意味着在任何计算或方法调用中根据 equals() 交换任何两个相等的实例 x 和 y 不会产生明显的行为变化。

Optional就是这样一个类。

Optional a = Optional.of(new ArrayList<String>());
Optional b = Optional.of(new ArrayList<String>());
assertEquals(a, b); // passes as `equals` delegated to the lists

b.get().add("a");

// now bite the last bullet
assertTrue(a.get().isEmpty()); // passes
assertTrue(b.get().isEmpty()); // throws

是我读错了,还是需要更准确?

Update

Eran 的回答是有道理的(他们是no more相等),但让我移动目标:

...
assertEquals(a, b); // now, they are still equal
assertEquals(m(a, b), m(a, a)); // this will throw
assertEquals(a, b); // now, they are equal, too

让我们定义一个有趣的方法m,它会进行一些突变并再次撤消它:

int m(Optional<ArrayList<String>> x, Optional<ArrayList<String>> y) {
    x.get().add("");
    int result = x.get().size() + y.get().size();
    x.get().remove(x.get().size() - 1);
    return result;
}

我知道这是一种奇怪的方法。但我想,它符合“任何计算或方法调用”的资格,不是吗?


它们可以自由替换当相等时,这意味着在任何计算或方法调用中根据 equals() 交换任何两个相等的实例 x 和 y 不会产生明显的行为变化

Once b.get().add("a");被执行,a不再是equals to b,所以你没有理由期望assertTrue(a.get().isEmpty()); and assertTrue(b.get().isEmpty());会产生相同的结果。

基于值的类是不可变的这一事实并不意味着您不能改变存储在此类实例中的值(如though may contain references to mutable objects)。这仅意味着一旦您创建了Optional实例与Optional a = Optional.of(new ArrayList<String>()),你不能变异a保存对不同的引用ArrayList.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

基于值的类混乱 的相关文章

随机推荐