ブール値が設定されていない場所を知る必要がある状況がある場合(たとえば、その未設定の値が親値から継承する必要がある場合)Javaブールプリミティブ(および他の言語)は明らかに適切ではありません。
これを達成するためのベストプラクティスは何ですか? 3つの状態すべてを表現できる新しい単純なクラスを定義するか、Javaブールクラスを使用し、nullを使用して未設定の状態を示しますか?
Boolean a = true;
Boolean b = false;
Boolean c = null;
私はそれを使います。それは最も簡単です。
別の方法は、列挙型を使用することです。ボクシングが必要ないので、おそらくそれはさらに良くて速いです:
public enum ThreeState {
TRUE,
FALSE,
TRALSE
};
クラスのユーザーがスリーステートブール値を気にする必要がないという最初の利点があります。引き続きtrue
とfalse
を渡すことができます。 null
が気に入らない場合でも、ここではその意味についてほとんど説明されていないため、クラスでpublic static final Boolean tralse = null;
を作成できます。
Java 8)には、オプションオプションもあります。
public static final Optional<Boolean> TRI_TRUE = Optional.of(true);
public static final Optional<Boolean> TRI_FALSE = Optional.of(false);
public static final Optional<Boolean> TRI_UNKNOWN = Optional.empty();
ボーナスとして、これらすべてのmapおよびconsumeメソッドを取得します。
Java固有ではありませんが、このシナリオでの私自身の好みは、ThreeStateクラスまたは列挙型を定義して使用することです。前述のように、ドメイン固有としてTrue、False、およびUndefined(またはDefaultまたはUnset)を使用します。用語が指示します)。 null
で未設定/未定義を表すよりも、より良く、より自然で、より自己文書化されているように感じます。
@Nullable Boolean
が私の投票を獲得します。
Nullを使用して何かの状態を表すのは、設計が不十分です。それは説明的ではなく、維持するのが難しいです。明示的に何も設定されていない場合は、デフォルトの状態のStateオブジェクトが必要です。例えば:
if(state == null) {
doSomething();
}
これは、予想される状態が何であるかについては何も教えてくれません。このようなものはそれをより明確にします。
if(state.awaitingSet()) {
doSomething();
}
拡張性は言うまでもありません。 fourth状態が必要な場合はどうなりますか?
値が0、1、2のint(整数)を使用して、プログラム内で処理するだけです。
場合によります。ここで、親の値から値を継承する必要がある場合は未設定になると述べています。ある種のデータ階層がありますか?このようなもの:
Parent a {
boolean val = true;
boolean val2 = false;
}
Child b {
boolean val = false;
//here val2 should be unset!
}
この場合、可能であれば、子にval2を含めないでください。ルックアップロジックは、変数が見つからない場合は親から値を検索するようにします。
@vohoに追加するために、Optionalはラムダともうまく機能し、潜在的にクリーンな構造を作成します。
public class Node {
private Node parent;
private Optional<Boolean> something = Optional.empty();
public boolean isSomething() {
return something.orElseGet(() -> {
if (parent != null)
return parent.isSomething();
return false;
});
}
public void setSomething(boolean v) {
this.something = Optional.of(v);
}
}
ただし、ブール値とnullチェックよりも明らかに優れているわけではありません。
public class Node {
private Node parent;
private Boolean something;
public boolean isSomething() {
if (something != null)
return something;
if (parent != null)
return parent.isSomething();
return false;
}
public void setSomething(boolean v) {
this.something = v;
}
}