Überprüfen Sie, ob null Boolean true ist, was zu einer Ausnahme führt

169

Ich habe folgenden Code:

Boolean bool = null;

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

Warum führt meine Überprüfung der Booleschen Variablen "bool" zu einer Ausnahme? Sollte es nicht einfach direkt an der if-Anweisung vorbei springen, wenn es "sieht", dass es nicht wahr ist? Wenn ich die if-Anweisung entferne oder überprüfe, ob sie NICHT null ist, verschwindet die Ausnahme.

Vogelmann
quelle
3
Die obigen Antworten zum Entpacken von Objekten sind alle korrekt. Der Vollständigkeit halber können Sie Ihren Code jedoch auch so ändern, dass anstelle des Objekt-Wrappers "Boolean" das primitive "Boolean" verwendet wird. Sie sollten sich auch über den Unterschied zwischen einem Grundelement und einem Objekt informieren.
Marvo
In der Zwischenzeit ... wird if (bool == Boolean.TRUE)false ausgewertet, ohne eine Ausnahme zu generieren. Ich bin mir nicht sicher, ob dies in dem Fall beabsichtigt war, den ich gerade gefunden habe.
simon.watts
2
@ simon.watts , die für falsch sein würde boolsein nullODER wenn Booleanwurde explizit (und nicht als Verweis auf gebaut Boolean.TRUE). Also nicht zu empfehlen; im Gegensatz dazu if (Boolean.TRUE.equals(bool))würde wie erwartet funktionieren, einschließlich sicherer Umgang mit nullWert.
StaxMan

Antworten:

170

Wenn Sie eine haben boolean, kann es entweder trueoder sein false. Doch wenn Sie ein Booleanes kann entweder Boolean.TRUE, Boolean.FALSEoder nullwie jedes andere Objekt.

In Ihrem speziellen Fall löst Ihr Booleanis nullund die ifAnweisung eine implizite Konvertierung aus, die booleandas erzeugt NullPointerException. Möglicherweise benötigen Sie stattdessen:

if(bool != null && bool) { ... }
K-Ballo
quelle
23
Technisch gesehen Booleankann a eine beliebige Anzahl von echten Instanzen sein, nicht nur Boolean.TRUE. Zum Beispiel new Boolean(true).
Steve Kuo
1
Ich habe Schwierigkeiten zu verstehen, warum if (myBoolean)(wo myBooleanist Boolean) kein Compilerfehler oder zumindest eine Warnung ausgelöst wird. Dies ist sicher ein Gotcha.
Josh M.
1
@ JoshM. Dies liegt daran, dass Java das Verpacken und Entpacken von Wrappern durchführt: docs.oracle.com/javase/tutorial/java/data/autoboxing.html
Vinicius
3
@ Vinicius sicher, aber der Compiler sollte in diesem Fall entweder die Null für uns tun, zumindest durch eine Compiler-Warnung.
Josh M.
2
@ JoshM. Kann nicht mehr zustimmen :)
Vinicius
402

Wenn Sie keine zusätzlichen Nullprüfungen mögen:

if (Boolean.TRUE.equals(value)) {...}
AvrDragon
quelle
1
@ AvrDragon: Ist gleich erforderlich? Operator == funktioniert hier, da Boolean nur zwei Werte hat
Atul
7
@Atul Ja, hier ist gleich erforderlich. Weil (new Boolean (true) == new Boolean (true)) .... false ist. Grund: Boolean ist nur eine Klasse und kann wie jede andere Klasse in Java mehrere Instanzen haben.
AvrDragon
35
Ja, das ist eine Schande, der Konstruktor sollte privat sein, damit sichergestellt ist, dass es sich um einen Twingleton handelt ...
fortran
15
@fortran +1 für "Twingleton".
Bennett McElwee
1
Es macht absolut keinen Sinn, Apache BooleanUtils über diese Redewendung zu verwenden.
StaxMan
82

Verwenden Sie die Apache BooleanUtils .

(Wenn Spitzenleistung die wichtigste Priorität in Ihrem Projekt ist, schauen Sie sich eine der anderen Antworten für eine native Lösung an, für die keine externe Bibliothek erforderlich ist.)

Das Rad nicht neu erfinden. Nutzen Sie das, was bereits gebaut wurde, und nutzen Sie isTrue():

BooleanUtils.isTrue( bool );

Überprüft, ob ein BooleanWert wahr ist, und verarbeitet ihn nulldurch Rückgabe false.

Wenn Sie nicht auf die Bibliotheken beschränkt sind, die Sie "einschließen" dürfen, gibt es eine Reihe großartiger Hilfsfunktionen für alle Arten von Anwendungsfällen, einschließlich Booleansund Strings. Ich schlage vor, Sie lesen die verschiedenen Apache-Bibliotheken durch und sehen, was sie bereits bieten.

Joshua Pinter
quelle
59
Das Rad neu zu erfinden scheint nicht so schlimm, wenn die Alternative darin besteht, eine externe Bibliothek für etwas so Grundlegendes wie dieses zu verwenden.
Paul Manta
3
@PaulManta Ich stimme zu, wenn dies das einzige ist, was Sie jemals in den Apache Utils-Bibliotheken verwenden würden, aber die vorgeschlagene Idee ist, die Bibliotheken zu "durchsuchen", um sich anderen hilfreichen Funktionen auszusetzen.
Joshua Pinter
1
Die Verwendung dieser Bibliotheken führt zu Leistungseinbußen. Für solche grundlegenden Dinge, die Teil der Sprache sind, sollten Sie keine Bibliotheken verwenden.
ACV
6
Diese Bibliothek erfindet das Rad neu. Ich versuche solche Bibliotheken so weit wie möglich zu meiden.
mschonaker
3
@mschonaker Wenn Apache BooleanUtils das Rad neu erfindet, welches ist das Originalrad ? Die Idee ist zu vermeiden, eine Reihe von Hilfsfunktionen zu erstellen, die nachahmen, was bereits in solchen Bibliotheken getan wurde. Ich verwende toStringYesNodiese Bibliothek auch in allen meinen Anwendungen.
Joshua Pinter
13

BooleanTypen können sein null. Sie müssen eine nullÜberprüfung durchführen, wie Sie sie eingestellt haben null.

if (bool != null && bool)
{
  //DoSomething
}                   
fastcodejava
quelle
3
Was ist falsch an dieser Antwort? Es ist nicht die Überprüfung des Bools, die die Ausnahme auslösen würde. Unnötige Abstimmungen.
Dodexaeder
2
Ich bin damit einverstanden, dass es eine völlig vernünftige Antwort ist. Sie könnten jedoch die Ausnahmebehandlung loswerden.
Marvo
14
Die Ausnahmeübergabe ist nicht erforderlich und wird daneben auf eine Weise durchgeführt, die für Anfänger ein schlechtes Beispiel ist. Dies verdient eine Ablehnung, IMO. (Ja ... ich weiß, dass es aus dem Beispielcode stammt, aber das Wiederholen in der Antwort scheint dies zu bestätigen.)
Stephen C
1
Was ist dann der richtige Weg? Ich sehe deine Antwort hier nicht.
Marvo
5
Der richtige Weg ist der oben beschriebene. Keine Ausnahmebehandlung. Außerdem ist die Ausnahmebehandlung zu allgemein und wird nicht empfohlen.
Vellvisher
8

Oder mit der Leistung von Java 8 Optional können Sie auch einen solchen Trick ausführen:

Optional.ofNullable(boolValue).orElse(false)

:) :)

Vorbehalt
quelle
5

Boolean ist die Objekt-Wrapper-Klasse für den primitiven Boolean. Diese Klasse kann wie jede Klasse tatsächlich null sein. Aus Leistungs- und Speichergründen ist es immer am besten, das Grundelement zu verwenden.

Die Wrapper-Klassen in der Java-API dienen hauptsächlich zwei Zwecken:

  1. Bereitstellung eines Mechanismus zum "Umschließen" von Grundwerten in ein Objekt, sodass die Grundelemente in Aktivitäten aufgenommen werden können, die für Objekte reserviert sind, z. B. als zu Sammlungen hinzugefügt oder von einer Methode mit einem Objektrückgabewert zurückgegeben werden.
  2. Bereitstellung einer Auswahl von Dienstprogrammfunktionen für Grundelemente. Die meisten dieser Funktionen beziehen sich auf verschiedene Konvertierungen: Konvertieren von Grundelementen in und von String-Objekten und Konvertieren von Grundelementen und String-Objekten in und von verschiedenen Basen (oder Radix) wie Binär, Oktal und Hexadezimal.

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

Orlan
quelle
0

Da Ihre Variable bool auf eine Null zeigt, erhalten Sie immer eine NullPointerException. Sie müssen die Variable zuerst irgendwo mit einem Wert ungleich Null initialisieren und dann ändern.

RicardoE
quelle
1
Wenn es nur so wäre, würde der catchBlock die NullPointerException behandeln. Das Problem hierbei ist, dass das OP versucht, eine Nullreferenz in ein Grundelement zu entpacken.
Mike Adler
"Sie werden immer" - Nicht immer, mit Ausnahme des Beispiels, vereinfachter Code, der zwischen dem Initialisieren der Variablen nullund dem anschließenden Testen nichts bewirkt . Vermutlich wäre echter Code nicht so einfach oder der gesamte ifTest könnte entfernt werden.
nnnnnn