关于泛型,我被告知铸造是坏的,并且通常有一些方法可以完全消除铸造,因为编译器在检查程序时能够做到最好。在ChangeListener添加ReadOnlyDoubleProperty似乎打败了这个理想。这是API中的缺陷,还是规则的例外,还是实际上有一些方法可以使代码看起来很好?
nodeA.heightProperty().addListener(new ChangeListener<Number>() {
@Override
public void changed(ObservableValue< ? extends Number > observable,
Number oldValue,
Number newValue ) {
final double ov = oldValue.doubleValue();
final double nv = newValue.doubleValue();
@SuppressWarnings("unchecked")
final ObservableValue<Double> ob = ( ObservableValue< Double > ) observable;
// do stuff
}
});
首先,我可以在ChangeListener上使用的最具体的类型参数是Number。我应该可以使用Double!它是DoubleExpression!由于这个问题,我必须将参数解包为changed
方法。请帮助减少这里的行数。 Lambdas可以减少行数,但我特别询问泛型。
答案 0 :(得分:5)
tl; dr:使用asObject。
首先请注意,在您发布的示例中,根本没有理由引用observable
参数,因为它必须与nodeA.heightProperty()
具有相同的引用。因此,您可以使用
nodeA.heightProperty().addListener(new ChangeListener<Number>() {
@Override
public void changed(ObservableValue< ? extends Number > observable,
Number oldValue,
Number newValue ) {
final double ov = oldValue.doubleValue();
final double nv = newValue.doubleValue();
// do stuff with nodeA.heightProperty() ...
}
});
这并不奇怪:事实上我认为我不需要引用传递给此方法的observable,因为我总是使用相同的模式。
至于ReadOnlyDoubleProperty
实现ObservableValue<Number>
而不是ObservableValue<Double>
,这可能是一个便利功能,也可能是设计缺陷,具体取决于您的观点。 (参见讨论here,以及其他地方......)。解决方法是在asObject()
上调用ReadOnlyDoubleProperty
,该ReadOnlyObjectProperty<Double>
会返回与ReadOnlyDoubleProperty
双向绑定的ObservableValue<Double>
,并实现nodeA.heightProperty().asObject().addListener(new ChangeListener<Double>() {
@Override
public void changed(ObservableValue< ? extends Double > observable,
Double oldValue,
Double newValue ) {
final double ov = oldValue.doubleValue();
final double nv = newValue.doubleValue();
// do stuff
}
});
:
ov
(取消装箱也会使nv
和nodeA.heightProperty().asObject().addListener((obs, oldValue, newValue) -> {
// obs is now an ObservableValue<Double>, if you need it
// oldValue is a Double, which can be treated as a double via unboxing
// similarly newValue is a Double
// do stuff..
});
在上面变得多余。)
你当然可以用lambdas使这个更好:
formatter