Booleano vs booleano in Java


197

Ci sono discussioni su Integervs intin Java. Il valore predefinito del primo è nullmentre nel secondo è 0. Che ne dici di Booleanvs boolean?

Una variabile nella mia applicazione può avere 0/ 1valori. Vorrei usare boolean/ Booleane preferisco non usare int. Posso usare Boolean/ booleaninvece?


2
Per motivi di progettazione del sistema sceglierei Boolean poiché ha l'opzione "L'utente non ha ancora deciso" che non è né uguale a "true", né "false". Vorrei usare la primitiva booleana solo nei casi in cui sono sicuro al 100% che le opzioni true / false siano sufficienti. Nel database l'opzione NULL è di solito disponibile senza problemi (o semplicemente rimuovendo le restrizioni NOT NULL su richieste successive)
CsBalazsHungary

2
Duplicato esatto di Qual è la differenza tra booleano e booleano in Java? (perché GWT non fa differenza).
Dan Dascalescu,

Risposte:


272

, puoi usare Boolean/ booleaninvece.

Il primo è Object e il secondo è di tipo primitivo.

  • Sul primo, otterrai più metodi che saranno utili.

  • Il secondo è economico considerando le spese di memoria. Il secondo ti farà risparmiare molta più memoria, quindi provaci

Ora scegli la tua strada.


70
Avresti potuto dirlo come "il secondo ti farà risparmiare molta più memoria, quindi provaci". I metodi utili su Boolean possono essere per lo più invocati senza avere un'istanza di esso.
DJClayworth,

3
Finché si utilizza invece Boolean.valueOf (valore) del nuovo booleano (valore), la memoria non dovrebbe essere un problema.
Greg Case,

2
perché AsyncTaskpuoi usare solo Booleaninvece di boolean.
Raptor

99
Va notato che un booleano in realtà ha 3 stati ... true, falsee nulldove un booleano ha i 2 stati ( truee false)
logici

14
Boolean is trillean :)
Topera,

50

Boolean avvolge il tipo primitivo booleano. In JDK 5 e versioni successive, Oracle (o Sun prima che Oracle li acquistasse) ha introdotto il boxbox automatico / unboxing , che essenzialmente consente di farlo

boolean result = Boolean.TRUE;

o

Boolean result = true; 

Che essenzialmente fa il compilatore,

Boolean result = Boolean.valueOf(true);

Quindi, per la tua risposta, è SÌ.


4
Nota: non è sempre possibile assegnare in modo sicuro Booleana a boolean. Se lo Booleanè nulle si tenta di assegnarlo a boolean, verrà lanciato a NullPointerExceptionin fase di esecuzione.
Duncan Luk,

se Booleanuna classe allora perché il valore è sempre falso anche se ho cambiato il valore da un'altra classe facendo riferimento alla stessa variabile booleana? qual è il punto di ciò Booleanquindi se non possiamo fare riferimento a classi di istanze diverse / passare come argomento?
user924

trovato una risposta, possiamo usarla AtomicBooleane fare riferimento da classi di differenza
user924

35

Sto un po 'estendendo le risposte fornite (dato che finora si concentrano sulla loro "propria" / terminologia artificiale concentrandosi sulla programmazione di un particolare linguaggio invece di occuparsi del quadro più ampio dietro la scena della creazione dei linguaggi di programmazione , in generale, cioè quando le cose come le considerazioni sulla sicurezza dei tipi e sulla memoria fanno la differenza):

int non è booleano

Tener conto di

    boolean bar = true;      
    System.out.printf("Bar is %b\n", bar);
    System.out.printf("Bar is %d\n", (bar)?1:0);
    int baz = 1;       
    System.out.printf("Baz is %d\n", baz);
    System.out.printf("Baz is %b\n", baz);

con uscita

    Bar is true
    Bar is 1
    Baz is 1
    Baz is true

Il codice Java sulla terza riga (bar)?1:0mostra che la barra ( booleana ) non può essere implicitamente convertita (castata) in un int . Sto sollevando questo argomento non per illustrare i dettagli dell'implementazione dietro JVM, ma per sottolineare che in termini di considerazioni di basso livello (come le dimensioni della memoria) si devono preferire i valori alla sicurezza del tipo. Soprattutto se quel tipo di sicurezza non è realmente / pienamente utilizzato come nei tipi booleani in cui i controlli vengono effettuati in forma di

se il valore \ in {0,1} viene quindi trasmesso al tipo booleano, altrimenti genera un'eccezione.

Tutto solo per affermare che {0,1} <{-2 ^ 31, .., 2 ^ 31 -1}. Sembra un eccesso, vero? La sicurezza dei tipi è veramente importante nei tipi definiti dall'utente, non nella fusione implicita di primitivi (sebbene gli ultimi siano inclusi nel primo).

I byte non sono tipi o bit

Ricorda che in memoria la tua variabile nell'intervallo di {0,1} occuperà comunque almeno un byte o una parola (xbit in base alla dimensione del registro) a meno che non sia stata curata in modo particolare (ad es. Imballata bene in memoria - 8 "booleana" bit in 1 byte - avanti e indietro).

Preferendo la sicurezza del tipo (come nel mettere / racchiudere il valore in una scatola di un tipo particolare) piuttosto che nell'imballaggio di valore extra (ad es. Usando i bit shift o l'aritmetica), si sceglie effettivamente di scrivere meno codice piuttosto che guadagnare più memoria. (D'altra parte si può sempre definire un tipo di utente personalizzato che faciliterà tutte le conversioni che non valgono il valore booleano).

parola chiave vs. tipo

Infine, la tua domanda riguarda il confronto tra parola chiave e tipo . Ritengo sia importante spiegare perché o in che modo otterrai prestazioni utilizzando / preferendo le parole chiave ("contrassegnate" come primitive ) rispetto ai tipi (normali classi composite definibili dall'utente utilizzando un'altra classe di parole chiave ) o in altre parole

boolean foo = true;

vs.

Boolean foo = true;

La prima "cosa" (tipo) non può essere estesa (sottoclasse) e non senza motivo. In effetti, la terminologia Java delle classi primitive e di wrapping può essere semplicemente tradotta in valore inline (un LITERAL o una costante che viene sostituita direttamente dal compilatore ogni volta che è possibile inferire la sostituzione o, in caso contrario, fallback nel wrapping del valore).

L'ottimizzazione è ottenuta grazie a banali:

"Meno operazioni di casting runtime => più velocità."

Questo è il motivo per cui, quando viene fatta l'inferenza del tipo effettivo, può (ancora) finire per creare un'istanza della classe di wrapping con tutte le informazioni sul tipo, se necessario (o convertire / eseguire il casting in tale).

Quindi, la differenza tra il valore booleano e booleana è esattamente nella compilazione e runtime (un po 'lontano in corso, ma quasi come instanceof vs getClass () ).

Infine, l'autoboxing è più lento dei primitivi

Si noti che Java può eseguire il box automatico è solo uno "zucchero sintattico". Non accelera nulla, ti permette solo di scrivere meno codice. Questo è tutto. Il cast e il wrapping nel contenitore di informazioni sul tipo vengono comunque eseguiti. Per motivi di prestazioni, scegliere l'aritmetica che salterà sempre le pulizie extra della creazione di istanze di classe con informazioni sul tipo per implementare la sicurezza del tipo. La mancanza di sicurezza del tipo è il prezzo da pagare per ottenere prestazioni. Per il codice con espressioni con valori booleani la sicurezza del tipo (quando si scrive meno e quindi codice implicito ) sarebbe fondamentale, ad esempio per i controlli di flusso if-then-else.


16

Puoi usare le costanti booleane - Boolean.TRUEe Boolean.FALSEinvece di 0e 1. Puoi creare la tua variabile di tipo booleanse la primitiva è ciò che stai cercando. In questo modo non dovrai creare nuovi Booleanoggetti.


4

Un'osservazione: (anche se questo può essere considerato un effetto collaterale)

essere un primitivo booleano può dire sì o no.

Boolean è un oggetto (può riferirsi a yes o no o 'non so' cioè null)


3

Fondamentalmente i booleani rappresentano un tipo di dati primitivo in cui i booleani rappresentano un tipo di dati di riferimento. questa storia inizia quando Java vuole diventare puramente orientato agli oggetti, viene fornito il concetto di classe wrapper per arrivare a utilizzare il tipo di dati primitivo.

boolean b1;
Boolean b2;

b1e b2non sono uguali.


1

Puoi usare Boolean / boolean. La semplicità è la strada da percorrere. Se non hai bisogno di API specifiche (Collezioni, Stream, ecc.) E non prevedi di averne bisogno, usa una versione primitiva (booleana).

  1. Con le primitive garantisci di non passare valori nulli.
    Non cadrai in trappole come questa. Il codice seguente genera NullPointerException (da: booleani, operatori condizionali e autoboxing ):

    public static void main(String[] args) throws Exception { Boolean b = true ? returnsNull() : false; // NPE on this line. System.out.println(b); } public static Boolean returnsNull() { return null; }

  2. Usa Boolean quando hai bisogno di un oggetto, ad esempio:

    • Flusso di booleani,
    • Opzionale
    • Collezioni di booleani
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.