何时使用 JavaFX 属性 setter 和 getter,而不是直接使用 属性
When to use JavaFX properties setter and getter, instead of using the property directly
我熟悉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;}
}
我不明白的是when/why我会使用getter和setter方法,而不是直接使用属性?
我在想的是,您可能需要 getter and/or setter 中的一些自定义代码,这些代码可能会做一些预或 post manipulation/validation的数据,但是如果您创建自定义 getter and/or setter,那么您会得到不同的结果,具体取决于您使用的是 getter/setter 还是 属性直接,对我来说,这似乎很危险。
如果 getter/setter 只是调用 属性 的 get 和 set 方法,那为什么还要它们?
如有任何见解,我们将不胜感激。
JavaFX 属性 模式旨在扩展旧的标准 JavaBean 模式。因此,在您的示例中,根据 JavaBean 约定,您有一个类型为 double
的(读写)属性,名为 amount
。这是由两种方法决定的
public double getAmount() ;
public void setAmount(double amount);
JavaBean 模式允许一些有限的"observability" 通过"bound properties",其中bean 支持注册一个PropertyChangeListener
。
UI 工具包通常需要观察属性并响应变化。例如,Label
有 text
属性 是有意义的。如果 text
属性 发生变化,则需要通知 Label
,以便它知道重新绘制自己。乍一看,使用具有绑定属性的 JavaBeans 是一种实现此目的的方法。但是,在 UI 工具包中使用此机制会产生性能问题,因为如果不立即计算某个值,则无法通知该值不再有效。这意味着,例如,对于 属性.
的每个单独更改都会重新计算布局
JavaFX 团队的目标显然是定义一种模式
- 符合标准的 JavaBean 模式,并且
- 支持的可观察属性,其中每次值更改时无需重新计算依赖值即可跟踪失效 ("lazily observable values")
因此 JavaFX 解决方案是创建支持 ChangeListener
s 和 InvalidationListener
s 的属性,前者在值更改时收到通知,后者在值不再有效时收到通知。这意味着,例如,布局机制可以跟踪它当前是否有效,而无需在它变得无效时强制重新计算。布局只会在实际屏幕脉冲时(即渲染场景时)重新计算,并且只有在它无效时才会重新计算。
(作为快速概念验证,请考虑以下内容:
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
表示,这意味着它们基本上是 "lazily observable"。通过 属性 访问器方法(在您的示例中为 amountProperty()
)公开 属性 本身足以支持此功能。
然而,从语义上讲,公开一个 DoubleProperty
意味着该 bean 具有 double
类型的值。为了保持与旧 JavaBean 约定的兼容性,这个 bean 应该通过公开相应的 get
和 set
方法来宣传这一事实。因此,JavaFX 属性 模式需要 "property accessor" (amountProperty()
) 以及标准 JavaBean 方法(getAmount()
和 setAmount(...)
)。这意味着遵循 JavaFX 模式的 bean 可以在任何使用标准 JavaBean 模式的地方使用,例如 JPA.
请注意,为了使模式正常工作,amountProperty().get() == getAmount()
和 amountProperty().set(x)
与 setAmount(x)
具有相同的效果应该始终为真。这可以通过 get
和 set
方法 final
来保证(即使 bean class 被子 classed),如您的示例所示。
如果您自己调用这些方法来检索或更改 属性 的值,调用哪个方法并不重要,因为它们保证具有相同的效果。由于 JavaFX 属性 模式是 JavaBean 模式的扩展,因此调用 get
和 set
方法可能有轻微的偏好:在某种意义上访问值只需要 JavaBean功能,而不是完整的 JavaFX 属性 功能,因此仅依赖该功能可能具有一定的语义意义。然而,在实践中,使用哪种方式并没有什么区别。
我熟悉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;}
}
我不明白的是when/why我会使用getter和setter方法,而不是直接使用属性?
我在想的是,您可能需要 getter and/or setter 中的一些自定义代码,这些代码可能会做一些预或 post manipulation/validation的数据,但是如果您创建自定义 getter and/or setter,那么您会得到不同的结果,具体取决于您使用的是 getter/setter 还是 属性直接,对我来说,这似乎很危险。
如果 getter/setter 只是调用 属性 的 get 和 set 方法,那为什么还要它们?
如有任何见解,我们将不胜感激。
JavaFX 属性 模式旨在扩展旧的标准 JavaBean 模式。因此,在您的示例中,根据 JavaBean 约定,您有一个类型为 double
的(读写)属性,名为 amount
。这是由两种方法决定的
public double getAmount() ;
public void setAmount(double amount);
JavaBean 模式允许一些有限的"observability" 通过"bound properties",其中bean 支持注册一个PropertyChangeListener
。
UI 工具包通常需要观察属性并响应变化。例如,Label
有 text
属性 是有意义的。如果 text
属性 发生变化,则需要通知 Label
,以便它知道重新绘制自己。乍一看,使用具有绑定属性的 JavaBeans 是一种实现此目的的方法。但是,在 UI 工具包中使用此机制会产生性能问题,因为如果不立即计算某个值,则无法通知该值不再有效。这意味着,例如,对于 属性.
JavaFX 团队的目标显然是定义一种模式
- 符合标准的 JavaBean 模式,并且
- 支持的可观察属性,其中每次值更改时无需重新计算依赖值即可跟踪失效 ("lazily observable values")
因此 JavaFX 解决方案是创建支持 ChangeListener
s 和 InvalidationListener
s 的属性,前者在值更改时收到通知,后者在值不再有效时收到通知。这意味着,例如,布局机制可以跟踪它当前是否有效,而无需在它变得无效时强制重新计算。布局只会在实际屏幕脉冲时(即渲染场景时)重新计算,并且只有在它无效时才会重新计算。
(作为快速概念验证,请考虑以下内容:
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
表示,这意味着它们基本上是 "lazily observable"。通过 属性 访问器方法(在您的示例中为 amountProperty()
)公开 属性 本身足以支持此功能。
然而,从语义上讲,公开一个 DoubleProperty
意味着该 bean 具有 double
类型的值。为了保持与旧 JavaBean 约定的兼容性,这个 bean 应该通过公开相应的 get
和 set
方法来宣传这一事实。因此,JavaFX 属性 模式需要 "property accessor" (amountProperty()
) 以及标准 JavaBean 方法(getAmount()
和 setAmount(...)
)。这意味着遵循 JavaFX 模式的 bean 可以在任何使用标准 JavaBean 模式的地方使用,例如 JPA.
请注意,为了使模式正常工作,amountProperty().get() == getAmount()
和 amountProperty().set(x)
与 setAmount(x)
具有相同的效果应该始终为真。这可以通过 get
和 set
方法 final
来保证(即使 bean class 被子 classed),如您的示例所示。
如果您自己调用这些方法来检索或更改 属性 的值,调用哪个方法并不重要,因为它们保证具有相同的效果。由于 JavaFX 属性 模式是 JavaBean 模式的扩展,因此调用 get
和 set
方法可能有轻微的偏好:在某种意义上访问值只需要 JavaBean功能,而不是完整的 JavaFX 属性 功能,因此仅依赖该功能可能具有一定的语义意义。然而,在实践中,使用哪种方式并没有什么区别。