Controlla se null booleano è true risultati in eccezione


169

Ho il codice seguente:

Boolean bool = null;

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

Perché il mio controllo sulla variabile booleana "bool" genera un'eccezione? Non dovrebbe semplicemente saltare oltre l'istruzione if quando "vede" che non è vero? Quando rimuovo l'istruzione if o controllo se NON è null, l'eccezione scompare.


3
Le risposte sopra sull'unboxing degli oggetti sono tutte corrette. Per completezza, tuttavia, è possibile anche modificare il codice per utilizzare il "booleano" primitivo anziché il wrapper di oggetti "Booleano". Dovresti anche rinfrescarti sulla differenza tra una primitiva e un oggetto.
Marvo,

Nel frattempo ... if (bool == Boolean.TRUE)valuta false senza generare un'eccezione. Non sono sicuro che questo fosse intenzionale nel caso che ho appena trovato.
simon.watts

2
@ simon.watts che sarebbe falso per boolessere nullOR se Booleancostruito esplicitamente (e non come riferimento a Boolean.TRUE). Quindi non raccomandato; al contrario del if (Boolean.TRUE.equals(bool))quale funzionerebbe come previsto, compresa la gestione sicura del nullvalore.
StaxMan,

Risposte:


171

Quando hai un booleanpuò essere trueo false. Eppure, quando si ha un Booleanche può essere Boolean.TRUE, Boolean.FALSEo nullcome qualsiasi altro oggetto.

Nel tuo caso particolare, il tuo Booleanè nulle la ifdichiarazione innesca una conversione implicita a booleanquella che produce il NullPointerException. Potrebbe essere necessario invece:

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

23
Tecnicamente a Booleanpuò essere un numero qualsiasi di istanze vere, non solo Boolean.TRUE. Per esempio new Boolean(true).
Steve Kuo,

1
Faccio fatica a capire perché if (myBoolean)(dove si myBooleantrova Boolean) non viene generato un errore del compilatore o almeno un avviso. Questo è sicuramente un gotcha.
Josh M.,

1
@JoshM. Questo perché Java esegue Boxing e Unboxing di wrapper: docs.oracle.com/javase/tutorial/java/data/autoboxing.html
Vinicius

3
@Vinicius certo, ma il compilatore dovrebbe fare il null per noi in questo caso, almeno attraverso un avviso del compilatore.
Josh M.

2
@JoshM. Non posso essere più d'accordo :)
Vinicius,

402

Se non ti piacciono i controlli null aggiuntivi:

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

1
@AvrDragon: è richiesto uguale? L'operatore == lavora qui poiché Boolean ha solo due valori
Atul,

7
@Atul Sì, qui è richiesto uguale. Perché (new Boolean (true) == new Boolean (true)) è .... false. Motivo: Boolean è solo una classe e può avere più istanze come qualsiasi altra classe in Java.
AvrDragon,

35
sì, è un peccato, il costruttore dovrebbe essere privato, quindi è garantito che sia un twingleton ...
fortran

15
@fortran +1 per "twingleton".
Bennett McElwee,

1
Non ha assolutamente senso usare Apache BooleanUtils su questo idioma.
StaxMan,

82

Usa Apache BooleanUtils .

(Se le massime prestazioni sono la priorità più importante nel tuo progetto, cerca una delle altre risposte per una soluzione nativa che non richiede l'inclusione di una libreria esterna.)

Non reinventare la ruota. Sfrutta ciò che è già stato creato e utilizza isTrue():

BooleanUtils.isTrue( bool );

Verifica se un Booleanvalore è vero, gestendolo nullrestituendo false.

Se non sei limitato alle librerie che sei "autorizzato" a includere, ci sono un sacco di grandi funzioni di supporto per tutti i tipi di casi d'uso, incluso Booleanse Strings. Ti suggerisco di consultare le varie librerie Apache e vedere cosa offrono già.


59
Reinventare la ruota non sembra così male quando l'alternativa sta usando una libreria esterna per qualcosa di così semplice.
Paul Manta,

3
@PaulManta Sono d'accordo se questa è l'unica cosa che avresti mai usato nelle librerie di Apache Utils, ma l'idea suggerita è quella di "sfogliare" le librerie per esporti ad altre utili funzioni.
Joshua Pinter,

1
Vi è una penalità prestazionale per l'utilizzo di queste librerie. Quindi per tali cose di base che fanno parte del linguaggio, non dovresti usare le librerie.
ACV

6
Quella biblioteca sta reinventando la ruota. Cerco di evitare tali librerie il più possibile.
mschonaker,

3
@mschonaker Se Apache BooleanUtils sta reinventando la ruota, qual è la ruota originale ? L'idea è di evitare di creare un mucchio di funzioni di supporto che imitano ciò che è già stato fatto in librerie come questa. Uso anche toStringYesNoda questa libreria in tutte le mie applicazioni.
Joshua Pinter,

13

Booleani tipi possono essere null. Devi fare un nullcontrollo come hai impostato su null.

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

3
Cosa c'è di sbagliato in questa risposta? Non è il controllo del bool che genererebbe l'eccezione. Downvotes non necessari.
dodexahedron,

2
Sono d'accordo che sia una risposta perfettamente ragionevole. Tuttavia, è possibile eliminare la gestione delle eccezioni.
Marvo,

14
La gestione delle eccezioni non è necessaria e inoltre viene eseguita in un modo che è un cattivo esempio per i principianti. Questo merita un downvote, IMO. (Sì ... so che proviene dal codice di esempio, ma ripeterlo nella risposta sembra confermarlo.)
Stephen C

1
Qual è il modo GIUSTO allora? Non vedo la tua risposta qui.
Marvo,

5
Il modo giusto è quello sopra ... nessuna gestione delle eccezioni. Inoltre, la gestione delle eccezioni è troppo generale ed è scoraggiata.
Vellvisher,

8

O con la potenza di Java 8 Opzionale, puoi anche fare questo trucco:

Optional.ofNullable(boolValue).orElse(false)

:)


5

Booleano è la classe wrapper oggetto per il booleano primitivo. Questa classe, come qualsiasi classe, può effettivamente essere nulla. Per motivi di prestazioni e memoria è sempre meglio usare la primitiva.

Le classi wrapper nell'API Java hanno due scopi principali:

  1. Fornire un meccanismo per "avvolgere" i valori primitivi in ​​un oggetto in modo che le primitive possano essere incluse nelle attività riservate agli oggetti, come ad esempio essere aggiunte alle raccolte o restituite da un metodo con un valore restituito dall'oggetto.
  2. Fornire un assortimento di funzioni di utilità per le primitive. La maggior parte di queste funzioni sono correlate a varie conversioni: conversione di primitive da e verso oggetti String e conversione di primitive e oggetti String da e verso basi diverse (o radix), come binarie, ottali ed esadecimali.

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


0

poiché il bool della variabile punta a un valore null, otterrai sempre una NullPointerException, devi prima inizializzare la variabile da qualche parte con un valore non nullo, quindi modificarla.


1
Se così fosse, il catchblocco gestirà NullPointerException. Il problema qui è che l'OP tenta di decomprimere un riferimento null in una primitiva.
Mike Adler,

"lo farai sempre" - Non sempre, ad eccezione del campione, codice semplificato che non fa nulla tra l'inizializzazione della variabile nulle il suo test. Presumibilmente il codice reale non sarebbe così semplice o l'intero iftest potrebbe essere rimosso.
nnnnnn,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.