gpt4 book ai didi

java - ReadOnlyBooleanWrapper : incorrect behaviour when used with Bindings. 或

转载 作者:行者123 更新时间:2023-11-30 03:15:01 24 4
gpt4 key购买 nike

使用 Binding.or 绑定(bind)两个 ReadOnlyBooleanWrapper 对象时,我遇到了非常奇怪的行为。也就是说,当我对第一个参数执行 b1.set(true) 时,结果不正确(仍然是 false)。

这是一个简单的单元测试(失败):

@Test
public void testReadOnlyBooleanWrapper() {
// Fails!!!
testOr(new ReadOnlyBooleanWrapper(false), new ReadOnlyBooleanWrapper(false));
}

public void testOr(BooleanProperty b1, BooleanProperty b2) {
BooleanExpression or = b1.or(b2);

assertEquals(or.get(), b1.get() || b2.get());
b1.set(true);
assertEquals(or.get(), b1.get() || b2.get());
b1.set(false);
assertEquals(or.get(), b1.get() || b2.get());
}

请注意,使用 SimpleBooleanProperties 进行相同的测试效果很好:

@Test
public void testSimpleBooleanProperty() {
// Passes
testOr(new SimpleBooleanProperty(false), new SimpleBooleanProperty(false));
}

我可能在这里遗漏了一些点并滥用了属性,因为我无法想象实现中存在这样的错误! :)

感谢您提供任何解释的想法!

更新:

您的回答和评论让我走上了正轨:)我还没有解决方案,但我注意到,如果我将 or 绑定(bind)到 ReadOnlyProperties (应该公开)而不是包装器本身,那么测试通过:

@Test
public void testOrReadOnly() {
ReadOnlyBooleanWrapper b1 = new ReadOnlyBooleanWrapper(false);
ReadOnlyBooleanWrapper b2 = new ReadOnlyBooleanWrapper(false);

BooleanExpression or = b1.getReadOnlyProperty().or(b2.getReadOnlyProperty());

System.out.println("Condition " + or.get());
assertEquals(or.get(), b1.get() || b2.get());
b1.set(true);
System.out.println("Condition " + or.get());
assertEquals(or.get(), b1.get() || b2.get());
b1.set(false);
System.out.println("Condition " + or.get());
assertEquals(or.get(), b1.get() || b2.get());
}

这让我认为内部可读和可写属性与只读属性之间的同步在某种程度上被破坏了(?)

来自有关ReadOnlyBooleanWrapper的文档:

This class provides a convenient class to define read-only properties. It creates two properties that are synchronized. One property is read-only and can be passed to external users. The other property is read- and writable and should be used internally only.

最佳答案

这是一个错误(我认为)。

发生的情况是 or 绑定(bind)的实现实现了“or”的短路(这在 Bindings.java 中):

    @Override
public void invalidated(Observable observable) {
final BooleanOrBinding binding = ref.get();
if (binding == null) {
observable.removeListener(this);
} else {
// short circuit invalidation. This BooleanBinding becomes
// only invalid if the first operator changes or the
// first parameter is false.
if ((binding.op1.equals(observable) || (binding.isValid() && !binding.op1.get()))) {
binding.invalidate();
}
}
}

实现此功能的监听器将添加到 or 中的每个操作数:但是,ReadOnlyBooleanWrapper 将监听器委托(delegate)给其 ReadOnlyBooleanProperty(来自ReadOnlyBooleanWrapper.java):

@Override
public void addListener(InvalidationListener listener) {
getReadOnlyProperty().addListener(listener);
}

因此,在短路实现中,binding.op1.equals(observable)false(因为一个是 ReadOnlyBooleanWrapper,另一个是 ReadOnlyBooleanWrapper)是其 ReadOnlyBooleanProperty )。因此,这里的逻辑(错误地)假设第二个运算符已更改。由于第一个运算符的值为 true,因此实现的结论是 or 的计算不能更改,因此不会触发失效。因此,您的不会被重新评估。

正如您所发现的,解决方法是在计算绑定(bind)时使用包装的ReadOnlyBooleanProperty。我建议您报告此错误。

关于java - ReadOnlyBooleanWrapper : incorrect behaviour when used with Bindings. 或,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32847074/

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