ReadOnlyIntegerWrapper和ReadOnlyIntegerProperty有什么区别?

时间:2016-08-13 17:33:00

标签: javafx

何时使用哪一个? 如果它调用ReadOnlyIntegerWrapper,为什么我们仍然可以改变它的值?这是一个例子。

import javafx.beans.property.*;
public class ReadOnlyCheck{
    public static void main(String... args){
        ReadOnlyIntegerWrapper idWrapper = new ReadOnlyIntegerWrapper(100);
        ReadOnlyIntegerProperty id = idWrapper.getReadOnlyProperty();
        System.out.println("idWrapper:" + idWrapper.get());
        System.out.println("id:" + id.get());
        // Change the value
        idWrapper.set(101);
        System.out.println("idWrapper:" + idWrapper.get());
        System.out.println("id:" + id.get());
    }
}

所以我想问一下它们之间有什么区别。

已编辑:

如果ReadOnlyIntegerWrapper也可以更改值那么SimpleIntegerProperty()的用途是什么?他们为什么介绍ReadOnlyIntegerWrapper?

3 个答案:

答案 0 :(得分:2)

ReadOnlyIntegerProperty是ReadOnlyIntegerWrapper的超类。

因此,ReadOnlyIntegerWrapper是ReadOnlyIntegerProperty,其附加行为是定义只读属性的方便类。它创建两个同步的属性。一个属性是只读的,可以传递给外部用户。另一个属性是可读写的,只能在内部使用。

答案 1 :(得分:2)

SimpleIntegerProperty是一个允许用户读写值的类属性。但有时您确实希望限制对数据的写访问权限。在这种情况下,可以使用ReadOnlyIntegerPropertyWrapper。此属性可以修改,但也允许您提供属性的只读视图。简单地从返回类型为SimpleIntegerProperty的属性方法中返回ReadOnlyIntegerProperty并不能确保该属性不可写,因为该类的用户仍然可以将其强制转换为IntegerProperty并使用结果强制转换以设置属性

考虑Counter

的这两个版本
public class Counter {

    private final SimpleIntegerProperty value = new SimpleIntegerProperty();

    public void increment() {
        value.set(value.get() + 1);
    }

    public ReadOnlyIntegerProperty valueProperty() {
        return value;
    }
}

public class Counter {

    private final ReadOnlyIntegerWrapper value = new ReadOnlyIntegerWrapper();

    public void increment() {
        value.set(value.get() + 1);
    }

    public ReadOnlyIntegerProperty valueProperty() {
        return value.getReadOnlyProperty();
    }
}
Counter c = new Counter();
c.valueProperty().addListener((a,b, newValue) -> System.out.println(newValue));
c.increment();
((IntegerProperty)c.valueProperty()).set(-5);
c.increment();
如果使用第二个版本,

可以使用该类的第一个版本并生成ClassCastException

答案 2 :(得分:0)

我从此book中选择了以下示例。

@Override
public void start( Stage primaryStage ) throws Exception {
    ReadOnlyIntegerWrapper idWrapper = new ReadOnlyIntegerWrapper(100);
    ReadOnlyIntegerProperty id = idWrapper.getReadOnlyProperty();

    System.out.println("idWrapper.get() = " + idWrapper.get());
    System.out.println("id.get() = " + id.get());

    idWrapper.set(10);

    System.out.println("idWrapper.get() = " + idWrapper.get());
    System.out.println("id.get() = " + id.get());
}

我们可以看到,ReadOnlyIntegerWrapper是读/写属性,但是ReadOnlyIntegerProperty仅仅是读属性。 当我们向idWrapper属性写入新值时,id的值也会被更新(同步)。

那为什么我们要用一个代替另一个呢?这本书的作者添加了以下解释:

  

通常,包装器属性用作以下对象的私有实例变量:   一类。该类可以在内部更改属性。其之一   方法返回包装器类的只读属性,因此   对于外部世界,同一属性是只读的。

一个清晰的小例子

class Person{
    private ReadOnlyIntegerWrapper wealth = new ReadOnlyIntegerWrapper();

    /*We return the read-only property of the wrapper class*/
    public ReadOnlyIntegerProperty getWealth() {
        return wealth.getReadOnlyProperty();
    }

    private void setWealth(int newValue){
        //here, internally we can write a new value to the wealth property. 
    }
}