nullブール値がtrueであるかどうかをチェックすると、例外が発生します


169

私は次のコードを持っています:

Boolean bool = null;

try 
{
    if (bool)
    {
        //DoSomething
    }                   
} 
catch (Exception e) 
{
    System.out.println(e.getMessage());             
}

ブール変数 "bool"をチェックすると例外が発生するのはなぜですか?それが真ではないと「見た」とき、それはifステートメントのすぐ先をジャンプするべきではないでしょうか? ifステートメントを削除するか、nullでないかどうかを確認すると、例外はなくなります。


3
オブジェクトのボックス化解除に関する上記の答えはすべて正しいです。ただし、完全を期すために、オブジェクトラッパー「ブール」の代わりにプリミティブ「ブール」を使用するようにコードを変更することもできます。また、プリミティブとオブジェクトの違いを理解する必要があります。
Marvo

その間... if (bool == Boolean.TRUE)例外を生成せずにfalseを評価します。私が見つけたばかりの場合、これが意図的なものかどうかはわかりません。
simon.watts 2018

2
@ simon.wattsは、明示的に構築boolされたnull場合Boolean(およびへの参照としてではない場合)、ORであると偽になりますBoolean.TRUE。したがって、お勧めしません。対照的に、if (Boolean.TRUE.equals(bool))安全に取り扱いを含め、予想通りこれはうまくいくnull価値を。
StaxMan

回答:


171

あなたが持っている場合、booleanそれはまたはのどちらtruefalseです。しかし、あなたが持っているとき、BooleanそれはBoolean.TRUEBoolean.FALSEまたはnull他のオブジェクトのいずれかになります。

あなたの特定のケースでBooleanは、あなたのis nullifステートメントが暗黙的な変換をトリガーし、booleanそれがを生成しNullPointerExceptionます。代わりに必要になる場合があります:

if(bool != null && bool) { ... }

23
技術的には、Booleanだけでなく、任意の数の真のインスタンスを指定できますBoolean.TRUE。例えばnew Boolean(true)
Steve Kuo

1
if (myBoolean)myBooleanBoolean)がコンパイラエラーまたは少なくとも警告を発生させない理由を理解するのに苦労しています。これは確かに落とし穴です。
Josh M.

1
@JoshM。Javaはありませんので、これはボクシングアンボクシングラッパーのを:docs.oracle.com/javase/tutorial/java/data/autoboxing.html
ヴィニシウス

3
@Viniciusは確かですが、この場合、コンパイラは少なくともコンパイラの警告を通じてnullを実行する必要があります。
Josh M.

2
@JoshM。これ以上は同意できません:)
Vinicius

402

追加のnullチェックが必要ない場合:

if (Boolean.TRUE.equals(value)) {...}

1
@AvrDragon:は必要ですか?ブール値には2つの値しかないため、演算子==はここで機能します
Atul

7
@Atulはい、ここに等しいが必要です。(new Boolean(true)== new Boolean(true))は... falseだからです。理由:ブール値は単なるクラスであり、Javaの他のクラスと同じように複数のインスタンスを持つことができます。
AvrDragon

35
ええ、それは残念です、コンストラクタはプライベートでなければならないので、それがツイングルトンであることを保証します...
fortran

15
「twingleton」の@fortran +1。
Bennett McElwee

1
このイディオムでApache BooleanUtilsを使用してもまったく意味がありません。
StaxMan

82

Apache BooleanUtilsを使用します。

(プロジェクトでピークパフォーマンスが最も重要な優先順位である場合は、外部ライブラリを含める必要のないネイティブソリューションの他の回答の1つを確認してください。)

車輪を再発明しないでください。すでに構築されているものを活用して使用するisTrue()

BooleanUtils.isTrue( bool );

Boolean値がtrue かどうかをチェックし、をnull返すことで処理しfalseます。

含めることが「許可」されているライブラリに限定されない場合は、Booleansおよびを含むあらゆる種類のユースケースに対応する優れたヘルパー関数がたくさんありStringsます。さまざまなApacheライブラリを熟読し、それらがすでに提供しているものを確認することをお勧めします。


59
代替案がこれほど基本的なものに外部ライブラリを使用している場合、ホイールの再発明はそれほど悪くはありません。
Paul Manta 14

3
これは、あなたがしたいだけのものであれば@PaulManta私は同意し、これまでのApache Utilsのライブラリで使用していますが、提案アイデアはライブラリ「閲覧」、他の有用な機能に自分自身を公開することです。
Joshua Pinter

1
これらのライブラリを使用すると、パフォーマンスが低下します。したがって、言語の一部であるそのような基本的なものについては、ライブラリを使用しないでください。
ACV 2015年

6
その図書館は車輪を再発明しています。私はそのようなライブラリをできるだけ避けようとします。
mschonaker 2015

3
@mschonaker Apache BooleanUtilsがホイールを再発明している場合、元のホイールは何ですか?アイデアは、このようなライブラリで既に行われていることを模倣するヘルパー関数の束を作成しないようにすることです。私toStringYesNoはすべてのアプリケーションでこのライブラリからも使用しています。
Joshua Pinter 2015

13

Booleanタイプを指定できますnull。にnull設定したので、チェックを行う必要がありますnull

if (bool != null && bool)
{
  //DoSomething
}                   

3
この答えの何が問題になっていますか?例外をスローするのはブール値のチェックではありません。不必要な反対投票。
dodexahedron

2
私はそれが完全に合理的な答えであることに同意します。ただし、例外処理を取り除くことができます。
Marvo

14
例外処理は不要であり、それに加えて、初心者にとって悪い例となる方法で行われています。これは反対投票に値するIMOです。(そうです...私はそれがサンプルコードから来ていることを知っていますが、回答でそれを繰り返すことはそれを支持しているように見えます。)
スティーブンC

1
それでは正しい方法は何ですか?ここにあなたの答えはありません。
Marvo、2013年

5
正しい方法は上記のものです。例外処理はありません。また、例外処理は一般的すぎるためお勧めしません。
vellvisher

8

または、Java 8 Optionalの機能を使用して、そのようなトリックを実行することもできます。

Optional.ofNullable(boolValue).orElse(false)

:)


5

ブール値は、プリミティブブール値のオブジェクトラッパークラスです。このクラスは、他のクラスと同様に、nullにすることができます。パフォーマンスとメモリの理由から、プリミティブを使用することが常に最善です。

Java APIのラッパークラスは、主に2つの目的を果たします。

  1. オブジェクトにプリミティブ値を「ラップ」するメカニズムを提供して、プリミティブをコレクションに追加したり、オブジェクトの戻り値を使用してメソッドから返したりするなど、オブジェクト用に予約されたアクティビティに含めることができます。
  2. プリミティブにさまざまなユーティリティ関数を提供します。これらの関数のほとんどはさまざまな変換に関連しています。プリミティブとStringオブジェクト間の変換、およびプリミティブとStringオブジェクト間の2進数、8進数、16進数などの異なる基数(または基数)間の変換です。

http://en.wikipedia.org/wiki/Primitive_wrapper_class


0

変数boolがnullを指しているため、常にNullPointerExceptionが発生します。最初に変数をnull以外の値で初期化してから、変数を変更する必要があります。


1
それだけなら、catchブロックはNullPointerExceptionを処理します。ここでの問題は、OPがnull参照をプリミティブにアンボックスしようとすることです。
Mike Adler

「いつでも」 -常にではないが、サンプルを除いて、変数を初期化してからnullテストするまでの間に何もしない単純化されたコード。おそらく、実際のコードはそれほど単純ではないか、ifテスト全体が削除される可能性があります。
nnnnnn
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.