web-dev-qa-db-ja.com

ブール値のヌル値はいつ使用する必要がありますか?

Java booleantrueおよびfalseの値を許可し、Booleanはtruefalse、およびnullを許可します。 booleansをBooleansに変換し始めました。これは、次のようなテストでクラッシュを引き起こす可能性があります

Boolean set = null;
...
if (set) ...

テスト中

if (set != null && set) ...

不自然でエラーが発生しやすいようです。

Null変数でBooleansを使用するのが便利な場合はいつですか?そうでない場合、ラップされたオブジェクトの主な利点は何ですか?

更新:非常に多くの貴重な回答があったので、その一部を自分の回答にまとめました。私はせいぜいJavaの中間者なので、役に立つと思うものを見せようとしました。質問は「誤って表現されている」ことに注意してください(ブール値は「null値を持つことはできません」)

152

できる限り、booleanではなくBooleanを使用してください。これにより、多くのNullPointerExceptionsが回避され、コードがより堅牢になります。

Booleanは便利です、たとえば

  • コレクションにブール値を保存する(リスト、マップなど)
  • ヌル値を許可するブール値(たとえば、データベースのヌル値を許可するブール値列から取得)を表すnull値は、このコンテキストでは「trueかfalseかわからない」ことを意味する場合があります。
  • メソッドが引数としてオブジェクトを必要とするたびに、ブール値を渡す必要があります。たとえば、リフレクションまたはMessageFormat.format()などのメソッドを使用する場合。
239
JB Nizet

その意味があいまいであいまいなので、私はBooleanをほとんど使用しません。基本的に、3ステートロジック(true、false、またはunknown)があります。時々それを使用すると便利ですユーザーに2つの値の選択肢を与えたが、ユーザーはまったく答えなかったため、その情報を本当に知りたい(考えてみてください:NULLable database column)。

booleanからBooleanに変換する理由はありません。余分なメモリオーバーヘッド、NPEの可能性、および入力の減少が発生するためです。通常、Booleanを使用して生活を少し楽にするために、厄介な BooleanUtils.isTrue() を使用します。

Booleanが存在する唯一の理由は、Boolean型のコレクションを持つ機能です(ジェネリックでは、boolean、および他のすべてのプリミティブは許可されません)。

54

うわー、一体何?それは私だけですか、これらの答えはすべて間違っているか、少なくとも誤解を招いていますか?

ブールクラスは、ブールプリミティブ型のラッパーです。このラッパーを使用すると、オブジェクトまたはジェネリックを受け入れるメソッドでブール値を渡すことができます。すなわちベクトル。

ブールオブジェクトは、決してnullの値を持つことができません。ブールへのreferenceがnullの場合、ブールが作成されなかったことを意味します。

これは役に立つかもしれません: http://grepcode.com/file/repository.grepcode.com/Java/root/jdk/openjdk/6-b14/Java/lang/Boolean.Java

NULLブール参照は、他のNULL参照がある類似のロジックをトリガーするためにのみ使用する必要があります。 3ステートロジックに使用するのは面倒です。

編集:Boolean a = true;は誤解を招くステートメントであることに注意してください。これは本当にBoolean a = new Boolean(true);に近いものに相当します。ここでオートボクシングをご覧ください: http://en.wikipedia.org/wiki/Boxing_%28computer_science%29#Autoboxing

おそらく、これが混乱の多くの原因です。

EDIT2:以下のコメントをお読みください。これを組み込むために私の答えを再構築する方法のアイデアがある人は、そうしてください。

32
user606723

3つの簡単な理由があります。

  • データベースのブール値を表すため、truefalse、またはnull
  • xsd:booleanで宣言されたXMLスキーマのxsd:nillable="true"値を表す
  • ジェネリック型を使用できるようにする:List<Boolean>-List<boolean>は使用できません
24

質問に対する回答:回答から多くのことを学んだので、自分の質問に答えることは有益だと思いました。この回答は、私のような、問題を完全に理解していない人を助けることを目的としています。間違った言語を使用している場合は修正してください。

  • Nullの「値」は値ではなく、trueおよびfalseとは根本的に異なります。オブジェクトへのポインタがないことです。したがって、ブール値が3値であると考えるのは根本的に間違っています
  • ブールの構文は省略されており、参照がオブジェクトを指しているという事実を隠しています。

    Boolean a = true;

trueがオブジェクトであるという事実を隠します。他の同等の割り当ては次のとおりです。

Boolean a = Boolean.TRUE;

または

Boolean a = new Boolean(true);
  • 短縮構文

    if (a) ...

は、他のほとんどの割り当てとは異なり、がオブジェクト参照またはプリミティブである可能性があるという事実を隠しています。オブジェクトの場合、nullをテストしてNPEを回避する必要があります。私にとっては、平等性テストがある場合、これを覚えるのは心理的に簡単です:

if (a == true) ...

nullをテストするように求められる場合があります。したがって、短縮形はaがプリミティブの場合にのみ安全です。

私自身の推奨事項は次のとおりです。

  • 3値のロジックにはnullを使用しないでください。 trueとfalseのみを使用してください。
  • Booleanになる可能性があるため、メソッドからnullを返さないでください。 booleanのみを返します。
  • Booleanは、コンテナ内の要素のラップ、またはオブジェクトが必要なメソッドの引数にのみ使用します
11

プリミティブのラッパークラスは、オブジェクトが必要な場合に使用できます。コレクションは良いサンプルです。

何らかの理由でbooleanのシーケンスをArrayListに保存する必要があると想像してください。これは、booleanBooleanにボクシングすることで実行できます。

これについていくつかの言葉があります here

ドキュメントから:

Javaプログラマーが知っているように、int(または他のプリミティブ値)をコレクションに入れることはできません。コレクションはオブジェクト参照のみを保持できるため、プリミティブ値を適切なラッパークラス(intの場合は整数)にボックス化する必要があります。オブジェクトをコレクションから取り出すと、入れた整数を取得します。 intが必要な場合は、intValueメソッドを使用して整数のボックス化を解除する必要があります。このボックス化とボックス化解除はすべて苦痛であり、コードが乱雑になります。オートボクシングおよびアンボクシング機能は、プロセスを自動化し、痛みと混乱を取り除きます。

http://docs.Oracle.com/javase/1.5.0/docs/guide/language/autoboxing.html

10

場合によっては、すでに値を設定しているかどうかのブール値フィールドを区別するメカニズムが必要だと思います。

3
Thinhbk

Booleanラッパーは、trueおよびfalse以外に値が割り当てられたかどうかを確認する場合に役立ちます。次の3つの状態があります。

  • 本当
  • False
  • nullである未定義

booleanには2つの状態しかありません。

  • 本当
  • False

上記の違いは、BooleanTrue、またはFalseを持つことができるNull値のリストで役立ちます。

3
Ramesh PVK

上記のすべての良い答えについて、JavaサーブレットのHttpSessionクラスで具体的な例を挙げます。この例があなたがまだ持っているかもしれないいくつかの質問を明確にするのに役立つことを願っています。

セッションの値を保存および取得する必要がある場合は、setAttribute(String、Object)およびgetAttribute(String、Object)メソッドを使用します。そのため、ブール値の場合、httpセッションに格納する場合はブールクラスを使用する必要があります。

HttpSession sess = request.getSession(false);
Boolean isAdmin = (Boolean) sess.getAttribute("admin");
if (! isAdmin) ...

属性値が設定されていない場合、最後の行でNullPointerExceptionが発生します。 (これが私をこの投稿に導いた理由です)。したがって、使用するかどうかに関係なく、3つの論理状態はここにあります。

1
Wacker

ブール値は、3つの状態が必要な場合に非常に役立ちます。ソフトウェアテストのように、Testが渡された場合はtrueを送信し、失敗した場合はfalseを送信し、テストケースが中断した場合はテストケースが実行されないことを示すnullを送信します。

1
Aamir

ブールラッパーの** null **値には多くの用途があります! :)

たとえば、フォームに「ニュースレター」という名前のフィールドがあり、ユーザーがサイトのニュースレターを希望するかどうかを示します。ユーザーがこのフィールドの値を選択しない場合、その状況にデフォルトの動作を実装することができます(送信しますか?送信しませんか?再度質問しますか?など)。明らかに、設定されていない(または選択されていない、または** null **)は、trueまたはfalseと同じではありません。

ただし、「not set」がモデルに適用されない場合は、ブールプリミティブを変更しないでください;)

1
dcasanueva

ブール要素の厳密な定義では、2つの値のみがあります。完璧な世界では、それは本当でしょう。現実の世界では、要素が欠落しているか不明である場合があります。通常、これにはユーザー入力が含まれます。画面ベースのシステムでは、編集によって強制される可能性があります。データベースまたはXML入力のいずれかを使用するバッチワールドでは、要素が簡単に欠落する可能性があります。

したがって、私たちが住んでいる非完全な世界では、ブールオブジェクトは、欠落または不明な状態をヌルとして表すことができるという点で優れています。結局のところ、コンピューターはすべての可能な状態を考慮し、例外をスローしてそれらを処理する必要がある現実世界をモデル化するだけです(ほとんどの場合、例外をスローすることが正しい応答になるユースケースがあるため)。

私の場合、入力XMLに要素が欠落している可能性があり、ブール値に割り当ててブール値に割り当ててからtrueまたはfalseテストを使用する前にnullをチェックできるため、ブールオブジェクトが完璧な答えでした。

ちょうど2セントです。

1
user3228876

ブール値の主な目的はヌル値です。 null値は、プロパティが未定義であることを示します、たとえば、データベースのnull許容列を取得します。

すべてをプリミティブなブール値からラッパーブール値に変換する必要がある場合は、次を使用して古いコードをサポートできます。

Boolean set = Boolean.FALSE; //set to default value primitive value (false)
...
if (set) ...
1
JMelnik

最良の方法は、ブール値を完全に回避することです。すべてのブール値は、コードの他の場所に条件文があることを意味するためです( http://www.antiifcampaign.com/ およびこの質問を参照してください:- ifステートメントなしでアルゴリズムを記述できますか? )。

ただし、実際には時々ブール値を使用する必要がありますが、すでに自分でわかっているように、ブール値の処理はエラーが発生しやすく、面倒です。したがって、可能な限りブール値を使用することをお勧めします。これからの例外は、nullを許可するブール列を持つレガシーデータベースかもしれませんが、マッピングでもそれを隠そうとします。

0