質問
ブール値が設定されていない場所を知る必要がある場合(たとえば、設定されていない値が親値から継承する必要がある場合)、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();
}
拡張性は言うまでもありません。 4番目の状態が必要な場合はどうなりますか?
状況によります。ここで、親の値から値を継承する必要がある場合は設定されないことに言及します。何らかのデータ階層がありますか?このようなもの:
Parent a {
boolean val = true;
boolean val2 = false;
}
Child b {
boolean val = false;
//here val2 should be unset!
}
この場合、可能であれば、単にChildにval2を含めないでください。変数が見つからない場合は、親の値を検索するようにルックアップロジックを設定します。
値0、1、2のint(整数)を使用し、プログラム内で処理します。
@vohoに追加するために、Optionalはlambdaともうまく機能し、構造を潜在的にクリーンにします。
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;
}
}
親クラスでブール値をnullに初期化し、子クラスでブール値が設定されているかどうかを確認するメソッドを構築します
親クラスで
private Boolean a = null;
public void setA(Boolean a) {
this.a = a;
}
public Boolean getA() {
return a;
}
子クラス内
if (a == true)
{
dothis;
}
else if (a == false)
{
dothat;
}
else
{
assert false : "Boolean a has not been set";
}
アサーションがオンになっていることを確認してください。アサーションは開発サイクルとテストサイクル専用であり、ランタイム例外用ではありません。
java.lang.Booleanがこれを行います。静的定数Boolean.TRUE、Boolean.Falseがあります。
プライベートブールmyBoolean;
必要なものはすべて必要です。Boolean.TRUEは同等性テストに合格しますが、「true」とは異なります。 (これはTRUEに自動ボックス化されます)。