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

标签 java javafx properties 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 中使用一些自定义代码来对数据进行一些前或后操作/验证,但是如果您创建自定义 getter 和/或 setter,您会得到不同的结果然后,取决于您是直接使用 getter/setter 还是属性,这对我来说似乎很危险。

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

对此的任何见解将不胜感激。

最佳答案

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

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

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

JavaFX 团队的目标显然是定义一个模式
  • 符合标准JavaBean模式,以及
  • 支持可观察的属性,每次值改变时无需重新计算依赖值即可跟踪失效(“懒惰的可观察值”)

  • 因此,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 中的值由这些 observable Properties 表示它同时支持失效监听器和更改监听器,这意味着它们基本上是“可延迟观察的”。通过属性访问器方法(在您的示例中为 amountProperty())公开属性本身足以支持此功能。

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

    请注意,要使模式正常工作,amountProperty().get() == getAmount() 应该总是正确的。还有那个amountProperty().set(x)setAmount(x) 效果相同.这可以通过制作 get 来保证(即使 bean 类是子类)和 set方法 final ,就像你的例子一样。

    如果您自己调用方法来检索或更改属性的值,则调用哪个并不重要,因为它们保证具有相同的效果。由于 JavaFX 属性模式是 JavaBean 模式的扩展,因此可能会稍微倾向于调用 getset方法:从某种意义上说,访问值只需要 JavaBean 功能,而不是完整的 JavaFX 属性功能,因此仅依赖该功能可能具有某种语义意义。然而,在实践中,你使用什么没有区别。

    关于java - 何时使用 JavaFX 属性 setter 和 getter,而不是直接使用属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33834215/

    相关文章:

    java - 任何自动化 Eclipse 工作区设置的方法?

    JavaFX 任务可调用

    properties - D:常量正确性——我做错了什么?

    java - 如何围绕用户输入创建一个新的链接列表?

    java - 我如何使用 apache commons HttpPost 发送文件并对请求的参数进行编码?

    java - 我的线程不会在指定时间内 hibernate

    java - 从 MS Access 中提取 OLE 对象(Word 文档)

    javafx - 如何在JavaFX的MenuButton中创建子菜单?

    Python Azure 事件中心使用事件属性

    c# - 设计时 Form 的自定义可浏览属性