何时使用JavaFX属性setter和getter,而不是直接使用该属性

我熟悉Java,但刚开始学习JavaFX,并专门了解JavaFX属性。 我理解Oracle的以下示例中显示的基本设计模式:

package propertydemo; import javafx.beans.property.DoubleProperty; import javafx.beans.property.SimpleDoubleProperty; class Bill { // Define a variable to store the property private DoubleProperty amountDue = new SimpleDoubleProperty(); // Define a getter for the property's value public final double getAmountDue(){return amountDue.get();} // Define a setter for the property's value public final void setAmountDue(double value){amountDue.set(value);} // Define a getter for the property itself public DoubleProperty amountDueProperty() {return amountDue;} } 

我不明白的是何时/为什么我会使用getter和setter方法,而不是直接使用Property?

我在想的是你可能想要在getter和/或setter中有一些自定义代码可能会对数据进行一些操作前/操作/validation,但是如果你创建了一个自定义的getter和/或setter,你会得到不同的结果那么,取决于你是否直接使用getter / setter或属性,这对我来说似乎很危险。

如果getter / setter只是调用Property的get和set方法,那么为什么要使用它们呢?

任何有关这方面的见解将不胜感激。

JavaFX属性模式旨在扩展旧的标准JavaBean模式。 因此,在您的示例中,根据JavaBean约定,您具有double类型的(读写)属性,称为amount 。 这由两种方法决定

 public double getAmount() ; public void setAmount(double amount); 

JavaBean模式允许通过“绑定属性”进行一些有限的“可观察性”,其中bean支持注册PropertyChangeListener 。 UI工具包通常需要观察属性并响应更改。 例如, Label有一个text属性是有意义的。 如果text属性发生更改,则需要通知Label ,以便它知道重新绘制自己。 乍一看,使用具有绑定属性的JavaBeans将是一种方法。 但是,在UI工具包中使用此机制会产生性能问题,因为如果不立即计算值,则无法通知值不再有效。 这意味着,例如,布局将在对属性的每次单独更改时重新计算。

JavaFX团队显然希望做的是定义一种模式

  1. 符合标准的JavaBean模式,和
  2. 支持的可观察属性,可以跟踪失效,而无需在每次更改值时重新计算相关值(“延迟可观察值”)

因此,JavaFX解决方案是创建支持ChangeListener的属性,这些属性在值更改时得到通知,而InvalidationListener则在值不再有效时通知。 这意味着,例如,布局机制可以跟踪它当前是否有效,而不会在它变为无效时强制重新计算。 布局将仅重新计算实际屏幕脉冲(即,在渲染场景时),并且仅在其无效时才重新计算。

(作为快速概念validation,请考虑以下事项:

 DoubleProperty width = new SimpleDoubleProperty(3); DoubleProperty height = new SimpleDoubleProperty(4); ObservableDoubleValue area = Bindings.createDoubleBinding(() -> { double a = width.get() * height.get(); System.out.println("Computed area: "+a); return a ; }, width, height); System.out.println("Area is "+area.getValue()); width.set(2); height.set(3); System.out.println("Area is "+area.getValue()); 

请注意,从不计算width为2且height仍为4的中间值。)

因此,JavaFX中的值由这些可观察的Properties表示,这些Properties支持失效侦听器和更改侦听器,这意味着它们基本上是“懒惰地可观察”。 通过属性访问器方法( amountProperty()公开属性本身就足以支持此function。

但是,在语义上,暴露DoubleProperty意味着bean的值为double类型。 为了保持与旧JavaBean约定的兼容性,此bean应该通过公开相应的getset方法来宣传这一事实。 因此,JavaFX Property模式既需要“属性访问器”( amountProperty() ),也需要标准的JavaBean方法( getAmount()setAmount(...) )。 这意味着遵循JavaFX模式的bean可以在使用标准JavaBean模式的任何地方使用,例如在JPA中 。

请注意,为了使模式正常工作,应始终确实是amountProperty().get() == getAmount()amountProperty().set(x)setAmount(x)具有相同的效果。 通过将getset方法set final ,可以保证(即使bean类是子类),如示例所示。

如果您自己调用方法来检索或更改属性的值,则无论您调用哪个方法都无关紧要,因为它们可以保证具有相同的效果。 由于JavaFX Property模式是JavaBean模式的扩展,因此调用getset方法可能会有一点点偏好:在某种意义上,访问该值只需要JavaBeanfunction,而不是完整的JavaFX属性function,因此可能使一些语义意义只依赖于该function。 然而,在实践中,您使用它没有任何区别。