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


159

Javaは、booleanの値を可能にtrueし、falseブールができますがtruefalsenullbooleansをBooleans に変換し始めました。これは、次のようなテストでクラッシュを引き起こす可能性があります

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

テスト中

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

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

Booleannull値を持つs を使用すると便利な場合はいつですか?そうでない場合、ラップされたオブジェクトの主な利点は何ですか?

更新:非常に多くの貴重な回答がありましたが、自分の回答にいくつかまとめました。私はせいぜいJavaの中間者なので、役立つと思われるものを示すようにしました。質問は「誤った表現」です(ブール値は「null値を持つことはできません」)が、他の人が同じ誤解を持っている場合に備えて、私はそれを残しました。


7
場合によっては、初期化されていない状態が必要で、Boolean変数をnull役立つように設定する必要があります。
nhahtdh 2012年

2
「Always」は、確認を敢えてしませんが少し強いですが、null実際に3番目の状態として使用されるかどうかのテストを期待します。
nhahtdh

6
ブール値をブール値に変換する理由はありますか?私はプリミティブ型に固執し、それを行う正当な理由がある場合にのみラップします。たとえば、参照によって変数を渡す必要がある場合などです。
jpe '25

7
また、このをチェックアウトする場合があります:thedailywtf.com/Articles/What_Is_Truth_0x3f_.aspx
biziclop

6
「NULL値のようなものはありませんでのブール」。A Booleanはオブジェクトであり、a booleanは「スカラー」です。Boolean参照がnullに設定されている場合、対応するBooleanオブジェクトが存在しないことを意味します。存在しないものの中に何かを置くことはできません。
Hot Licks

回答:


244

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

Boolean たとえば便利です

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

35
データベースのnull値は、"FileNotFound"を
Karl Johan

31
2つ目の箇条書きは、この質問に対する正しい答えの核心です。
Niels Brinch

3
密接ポイント3に関連する-一般的なクラスを拡張するとき、私は持っていたことをブールの別の用途は、ジェネリック型パラメータとしてある
アレックス・

6
「宇宙は知らない」以外の意味でnullの概念をオーバーロードすることは、3(またはそれ以上)の値の列挙型を使用するよりも弱いです。また、メソッドにパラメーターを渡すコードの読み取りをより明示的にします。
bluevector 2012年

16
または#4:(Boolean isSchrodinger‎CatAlive = null;申し訳ありませんが、抵抗できませんでした;))。
Matthieu

58

Booleanセマンティクスが曖昧で曖昧であるため、ほとんど使用しません。基本的に、true、false、またはunknownの3ステートロジックがあります。たとえば、ユーザーに2つの値のいずれかを選択させ、ユーザーがまったく応答せず、その情報を本当に知りたい場合(NULL可能なデータベース列など)に使用すると便利な場合があります。

私はから変換する理由見ないbooleanBoolean、それは余分なメモリのオーバーヘッド、NPEの可能性の少ないタイピングを紹介するように。通常、私は厄介なものを使用BooleanUtils.isTrue()して、での生活を少し簡単にしBooleanます。

が存在する唯一の理由は、タイプのBooleanコレクションを作成Booleanできることです(ジェネリックではboolean、他のすべてのプリミティブと同様に許可されません)。


1
ただし、これは外部ライブラリ(Apache commons)です。
nhahtdh 2012年

4
多値ロジックの場合は、列挙型を使用することをお勧めします。したがって、データ構造で使用する(自動)ボクシング変数にはブール値を残す必要があります。
jpe

39
ブール値を使用する場合、nullポインタ例外を回避するための便利なテストはBoolean.TRUE.equals(myBooleanObject)またはBoolean.FALSE.equals(myBooleanObject)です。
クリストファーパイゼルト2012年

10
ブール値オブジェクトには2つの状態しかありません- truefalsenullあるいないオブジェクトの状態ではなく、オブジェクト参照の状態。
Hot Licks

2
「誰かがブール値を評価するのに失敗するかもしれません... isTrue()メソッドを作ってみましょう...」のような共通部分をApacheに任せてください。これはユーティリティ関数の歴史の中で最もおかしなように聞こえます。それでも、どういうわけか、それは便利です...それはここで最大のwtfです。
corsiKa

33

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

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

ブール値オブジェクトの値をnullにすることはできません。あなたの場合は、参照ブールには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:以下のコメントを読んでください。これを組み込むために私の答えをどのように再構成するかについて誰かが考えている場合は、そうしてください。


2
「ブール値にnullの値を含めることはできません」というステートメントを理解できません。ブール値(Boolean a = true;)を作成し、aをnull(a = null;)に設定できます。エレガントでも賢明でもないかもしれませんが、それは可能です。
peter.murray.rust 2012年

7
あなたがするときBoolean a; aはBooleanオブジェクトへのポインターです。あなたがいる場合a = null;あなたがnullにあなたのブールを設定していない、あなたはnullにあなたの参照を設定しています。いますBoolean a = null; a.booleanValue();。このケースでは、さえ作成したことはありません Booleanオブジェクトを、したがって、それは、NullPointerExceptionがスローされます。さらに詳しい説明が必要な場合はお知らせください。
user606723 2012年

さらに、を実行するとBoolean a = true;、実際にはBoolean a = new Boolean(true);Thats として解釈されるある種の魔法を実行しますが、おそらくパフォーマンス上の理由から完全には正しくありませんが、ブール値がまだオブジェクトであることを認識しなければなりません。
user606723

7
@missingno、オブジェクトを処理するすべてのコードはこれを処理する必要があります。オブジェクト参照は、nullでもそうでなくてもかまいません。これは特別なケースではなく、特別な考慮を必要としません。
user606723 2012年

3
私のポイント@missingnoがありません。null参照値を考慮する必要があることに同意します。私はそれに対して決して反対しませんでした。ただし、オブジェクト参照の場合はこれを行う必要がありますnullブール参照は特別な場合ではありません。したがって、ヌルのブール参照値は特別な考慮を必要としません。
user606723 2012年

24

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

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

booleanOracleでは通常char(1) null「T」と「F」の値を使用するので、「」(マインドスタイリング)ではなく「ブール」を明示的に記述しました。したがって、(たとえば、Hibernateタイプのアダプタを使用する場合)nullになる可能性があります:)
Grzegorz Grzybek

2
ブール値にnullを許可しないデータベースはどれですか。列をnull可能に設定すると、データ型は問題になりません...
Michal B.

@MichalB。Sybaseの(およびSQL Serverの)ビット型のinfocenter.sybase.com/help/index.jsp?topic=/...
MMMMMM

@マーク- -いいえ、SQL ServerがNULL可能ビット許可しないmsdn.microsoft.com/en-us/library/ms177603.aspx
デヴィッド・M

11

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

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

    Boolean a = true;

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

Boolean a = Boolean.TRUE;

または

Boolean a = new Boolean(true);
  • 省略された構文

    if (a) ...

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

if (a == true) ...

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

私自身のために私は今推奨事項を持っています:

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

5
「new Boolean(whatever)」は使用しないでください。これにより、ヒープに新しいブール値がインスタンス化されます。しかし、ブール値は不変です。「Boolean.valueOf(whatever)」を使用して、何に応じてBoolean.TRUEまたはBoolean.Falseを指す参照を作成します。
simbo1905 2012

1
Javaの多くの問題の1つ(12年後のIMHO)は、古い言語にもあるnull値へのアプローチの不整合です。Scalaを見ると、nullまたは値(サブクラスNoneまたはSome)を持つことができる型付きOptionの概念があります。次に、myOption.getOrElse(defaultValue)を呼び出すことができます。scala-lang.org/api/current/scala/Option.htmlを参照してください。この機能は複雑ではありません。それでも新しいJVM言語に組み込まれているため、多くのライブラリで使用されています。これにより、Javaの「前世紀」の問題の一部がスケール「修正」されますが、JREで実行されるクラスファイルにコンパイルされます。
simbo1905 2012

10

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

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

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

ドキュメントから:

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

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


3

Booleanラッパーは、trueおよびとは別に値が割り当てられているかどうかを確認する場合に便利ですfalse。次の3つの状態があります。

  • 本当
  • 誤り
  • 定義されていません null

一方、boolean状態は2つしかありません。

  • 本当
  • 誤り

上記の違いは、やBooleanを持つことができる値のリストで役立ちます。TrueFalseNull


いいえ、それはnull状態ではなく、それが参照です。
Matsemann

私が意味したのは、ブール値を定義済みのTrue / Falseと未定義に使用できるということです。
Ramesh PVK

3

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


1

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

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

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

6
「主な目的はnull値です」。いいえ、ブール値の主な目的は、ブール値への参照をオブジェクトとして渡すことです。
user606723 2012年

@ user606723は同意しました、私が書いている間、私は私の心の中でデータベースのケースを参照していました。
JMelnik 2012年

1

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

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

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


1

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

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

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

ちょうど私の2セント。


1

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

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

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

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


0

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

ただし、実用的にはブール値を時々使用する必要がありますが、すでに自分でわかっているように、ブール値を使用するとエラーが発生しやすくなり、扱いにくくなります。したがって、可能な限りブール値を使用することをお勧めします。これの例外は、ヌル値可能なブール列を持つレガシーデータベースである可能性がありますが、マッピングでも非表示にしようとします。


ブール値の処理は、他のオブジェクトの処理と同じくらいエラーが発生しやすくなります。ところで、このリンクは、一般的な使用法ではなく、型チェックのためのIFの急増に反対しています。そして、変更がより困難になるため、これは「危険」です。したがって、IF自体には何も問題はありません。
ミスタースミス

質問に対する答えではありません。
Matsemann

@MisterSmith Imhoブールフラグはタイプチェック変数として誤用されることが多いため、リンクもここで適用できます。ブール値が特定の状況で適切なツールであるかどうかを考える必要があるというのは、単なるヒントにすぎません。「ブール値を完全に回避する」という文はもちろん非常に急進的で実際には不可能です。そのため、2番目の段落を追加しました。また、説明を明確にするために、「エラーが発生しやすく、扱いにくい」を追加しました。
Roland Schneider 2012年

0

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


2
列挙型はこれに最適ではありませんか?クライアントに対して予期しないNullPointerExceptionsが発生する可能性があるのとは対照的に、列挙型は明示的に「状態」を定義します
Kartik Chugh

ステートマシンでは常にブール値ではなく列挙型を優先します。新しい4番目の状態がビジネス要件にいつ到着するかはわかりません。
AnupamChugh
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.