1

私は単純なフィールドを持っています(実際にはプロパティです):

    private final SimpleObjectProperty<ObjectWithColor> colored;

ObjectWithColorクラスにはプロパティがSimpleObjectProperty<Color>あるため、名前が付けられました。

さて、このプロパティは時々どこにも当てはまらないことがあります。私がやりたいことは、null でない場合は の色ObjectExpression<Color>を返す、そうでない場合は BLACK を返すことです。colored

私はコンストラクタでこのコードを書きました:

colored = new SimpleObjectProperty<>();  
ObjectExpression<Color> color= Bindings.when(colored.isNotNull()).then(colored.get().colorProperty()). otherwise(Color.BLACK);

私が理解していないのは、そのコード行を実行しているNullPointerExceptionを取得する理由です。それが呼び出されることは理解していますが、その理由はわかりません。それは、colored が null でない場合にのみ呼び出されるべきではありませんか?

4

1 に答える 1

4

>それは、colored が null でない場合にのみ呼び出されるべきではありませんか?

いいえ。あなたのコードでいくつかの類推をしましょう:

SimpleObjectProperty<ObjectWithColor> colored = new SimpleObjectProperty<>();  
colored.get().colorProperty();

およびその派生クラスはすべてラッパー クラスであるため、PropertyfullName フィールドを文字列として (ラップ) 持つ Person クラスと考えることができます。したがって、上記の類推は次のとおりです。

Person person = new Person();
person.getFullName().toString();

getFullName() は null を返すため、getFullName().toString() で NullPointerException が発生します。

両方の比較について、仮定は次のとおりです。ラップされたフィールドにデフォルト値がないか、デフォルト コンストラクターで初期化されていません。

この仮定を続けましょう。この場合、
コンストラクターを介して値を初期化することにより、NullPointerException を回避できます。

Person person = new Person("initial full name");
person.getFullName().toString();

または呼び出しセッター:

Person person = new Person();
person.setFullName("Foo Bar");
person.getFullName().toString();

同じことがあなたのコードにも当てはまります:

SimpleObjectProperty<ObjectWithColor> colored = 
                     new SimpleObjectProperty<>(new ObjectWithColor(Color.RED));  
colored.get().colorProperty();

また

SimpleObjectProperty<ObjectWithColor> colored = new SimpleObjectProperty<>();
colored.set(new ObjectWithColor(Color.RED));
colored.get().colorProperty();

あなたの質問を正しく理解できたことを願っています。それにもかかわらず、一方で、「それは色付きが null でない場合にのみ呼び出されるべきではありませんか?」プロンプト、実際に をチェックしているときに、色付きが null でないことについて話しているlastSupplier.isNotNull()タイプミスではないと推測し、現在のコードに基づいて回答しました。


編集:ああ!それはタイプミスでした!
問題を生成できました。javafx.beans.binding.When#then()言及のドキュメントとして、このメソッドは以下を返します。

the intermediate result which still requires the otherwise-branch

したがって、ステートメントcolored.get().colorProperty()は到達可能でなければなりません。通常、バインド可能な if-then-else ブロックは、次のような用途向けに設計されています。

SimpleObjectProperty<Double> doubleProperty = new SimpleObjectProperty();
ObjectExpression<Double> expression = Bindings.when(doubleProperty.isNotNull()).then(doubleProperty).otherwise(-1.0);
System.out.println(doubleProperty.getValue() + "  " + doubleProperty.isNotNull().getValue() + "  " + expression.getValue());
doubleProperty.setValue(1.0);
System.out.println(doubleProperty.getValue() + "  " + doubleProperty.isNotNull().getValue() + "  " + expression.getValue());

出力:

null  false  -1.0
1.0  true  1.0

その結果、初期のデフォルト値を定義できます。

SimpleObjectProperty<ObjectWithColor> colored = new SimpleObjectProperty(new ObjectWithColor(Color.BLACK));

または、バインディングで ObjectWithColor.colorProperty を直接使用することもできます。

于 2013-11-08T00:37:50.047 に答える