Boolean vs Boolean in Java

195

Es gibt Diskussionen um Integervs intin Java. Der Standardwert des ersteren ist, nullwährend es im letzteren ist 0. Wie wäre es mit Booleanvs boolean?

Eine Variable in meiner Anwendung kann 0/ 1values ​​haben. Ich möchte boolean/ verwenden Booleanund möchte es lieber nicht verwenden int. Kann ich stattdessen Boolean/ booleanverwenden?

Neel
quelle
2
Aus Gründen des Systemdesigns würde ich Boolean wählen, da es die Option "Der Benutzer hat noch nicht entschieden" hat, die weder gleich "wahr" noch "falsch" ist. Ich würde ein boolesches Grundelement nur in Fällen verwenden, in denen ich zu 100% sicher bin, dass die Optionen wahr / falsch ausreichen. In der Datenbank ist die Option NULL normalerweise ohne Probleme verfügbar (oder indem einfach die Einschränkungen von NULL bei späterer Anforderung entfernt werden)
CsBalazsHungary
2
Exaktes Duplikat von Was ist der Unterschied zwischen Boolean und Boolean in Java? (weil GWT keinen Unterschied macht).
Dan Dascalescu

Antworten:

270

Ja, Sie können Boolean/ booleanstattdessen verwenden.

Das erste ist Objekt und das zweite ist primitiver Typ.

  • Auf der ersten Seite erhalten Sie weitere Methoden, die nützlich sein werden.

  • Der zweite ist billig, wenn man die Speicherkosten berücksichtigt. Der zweite spart Ihnen viel mehr Speicher

Nun wähle deinen Weg.

Jigar Joshi
quelle
70
Sie hätten dies so formulieren können: "Der zweite spart Ihnen viel mehr Speicher, also machen Sie es". Die nützlichen Methoden für Boolean können meistens ohne Instanz aufgerufen werden.
DJClayworth
3
Solange Sie stattdessen Boolean.valueOf (Wert) von new Boolean (Wert) verwenden, sollte der Speicher kein Problem darstellen.
Greg Case
2
denn AsyncTaskSie können nur Booleananstelle von verwenden boolean.
Raptor
98
Es sollte die eine Boolesche hat tatsächlich drei Zustände festgestellt werden ... true, falseund nullwo ein boolean hat die logischen 2 - Staaten ( trueund false)
respectTheCode
14
Boolean ist trillean :)
Topera
50

Boolean umschließt den booleschen primitiven Typ. In JDK 5 und höher hat Oracle (oder Sun, bevor Oracle sie gekauft hat) Autoboxing / Unboxing eingeführt , wodurch Sie dies im Wesentlichen tun können

boolean result = Boolean.TRUE;

oder

Boolean result = true; 

Was im Wesentlichen der Compiler tut,

Boolean result = Boolean.valueOf(true);

Für Ihre Antwort ist es also JA.

Buhake Sindi
quelle
4
Hinweis: Sie können nicht immer sicher zuordnen Booleanzu ein boolean. Wenn Ihr Booleanist nullund Sie versuchen, es einem zuzuweisen, wird es zur Laufzeit booleanein werfen NullPointerException.
Duncan Luk
Wenn Booleaneine Klasse, warum ist der Wert dann immer falsch, auch wenn ich den Wert einer anderen Klasse geändert habe, die auf dieselbe boolesche Variable verweist? Was ist der Sinn davon, Booleanwenn wir nicht auf verschiedene Instanzklassen verweisen können / als Argument übergeben?
user924
fand eine Antwort, wir können AtomicBooleansie aus Differenzklassen verwenden und referenzieren
user924
35

Ich erweitere die bereitgestellten Antworten ein wenig (da sie sich bisher auf ihre "eigene" / künstliche Terminologie konzentrieren und sich auf die Programmierung einer bestimmten Sprache konzentrieren, anstatt sich um das Gesamtbild hinter den Kulissen der Erstellung der Programmiersprachen im Allgemeinen zu kümmern , dh wenn es um Dinge geht wie Typensicherheit vs. Speicherüberlegungen machen den Unterschied):

int ist nicht boolesch

Erwägen

    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);

mit Ausgabe

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

Java-Code in der 3. Zeile (bar)?1:0zeigt, dass Balken ( Boolescher Wert ) nicht implizit in einen Int konvertiert (umgewandelt) werden können . Ich spreche dies nicht an, um die Details der Implementierung hinter JVM zu veranschaulichen, sondern um darauf hinzuweisen, dass man in Bezug auf Überlegungen auf niedriger Ebene (als Speichergröße) Werte der Typensicherheit vorziehen muss. Insbesondere, wenn diese Art von Sicherheit nicht wirklich / vollständig verwendet wird, wie bei booleschen Typen, bei denen Überprüfungen in Form von durchgeführt werden

Wenn der Wert \ in {0,1} ist, wird er in einen booleschen Typ umgewandelt, andernfalls wird eine Ausnahme ausgelöst.

Alles nur um zu sagen, dass {0,1} <{-2 ^ 31, .., 2 ^ 31 -1}. Scheint ein Overkill zu sein, oder? Die Typensicherheit ist bei benutzerdefinierten Typen wirklich wichtig, nicht beim impliziten Gießen von Grundelementen (obwohl die letzten im ersten enthalten sind).

Bytes sind keine Typen oder Bits

Beachten Sie, dass Ihre Variable aus dem Bereich von {0,1} im Speicher immer noch mindestens ein Byte oder ein Wort belegt (xbits abhängig von der Größe des Registers), sofern nicht speziell darauf geachtet wird (z. B. gut im Speicher verpackt - 8 "boolean"). Bits in 1 Byte - hin und her).

Indem man die Typensicherheit (wie beim Einfügen / Umschließen von Werten in eine Box eines bestimmten Typs) dem Packen von zusätzlichen Werten (z. B. durch Verwendung von Bitverschiebungen oder Arithmetik) vorzieht, entscheidet man sich effektiv dafür, weniger Code zu schreiben, anstatt mehr Speicher zu gewinnen. (Andererseits kann man immer einen benutzerdefinierten Benutzertyp definieren, der die gesamte Konvertierung erleichtert, die nicht wert ist als Boolean).

Schlüsselwort vs. Typ

Schließlich geht es bei Ihrer Frage um den Vergleich von Keyword und Typ . Ich glaube , dass es wichtig ist , zu erklären , warum oder wie genau werden Sie die Leistung erhalten , indem Sie / lieber Schlüsselwörter ( „markiert“ als primitive ) über Typen (normale Verbundbenutzerdefinierbare Klassen ein anderes Schlüsselwort Klasse ) oder in anderen Worten :

boolean foo = true;

vs.

Boolean foo = true;

Das erste "Ding" (Typ) kann nicht ohne Grund erweitert (Unterklasse) werden. Effektiv Java Terminologie von primitiven und Verpackungs Klassen kann einfach in übersetzt wird Inline - Wert (ein Literal oder eine Konstante, die durch die Compiler direkt ersetzt wird , wann immer es möglich ist , um die Substitution zu schließen , oder wenn nicht - nach wie vor Rückfall in den Wert Einwickeln).

Die Optimierung wird durch Trivialität erreicht:

"Weniger Laufzeit-Casting-Vorgänge => mehr Geschwindigkeit."

Das ist der Grund, warum die eigentliche Typinferenz (noch) dazu führen kann, dass die Wrapping-Klasse bei Bedarf mit allen Typinformationen instanziiert wird (oder in solche konvertiert / umgewandelt wird).

Also der Unterschied zwischen Boolean und Boolean liegt also genau in Compilation und Runtime (etwas weit fortgeschritten , aber fast als Instanz von vs. getClass () ).

Schließlich ist Autoboxing langsamer als Grundelemente

Beachten Sie die Tatsache, dass Java dies kann Autoboxing ausführen kann und nur ein "syntaktischer Zucker" ist. Es beschleunigt nichts, erlaubt Ihnen nur, weniger Code zu schreiben. Das ist es. Das Umwandeln und Umwickeln in einen Typinformationscontainer wird weiterhin durchgeführt. Wählen Sie aus Leistungsgründen Arithmetik, bei der die Erstellung von Klasseninstanzen mit Typinformationen zur Implementierung der Typensicherheit immer übersprungen wird. Mangelnde Typensicherheit ist der Preis, den Sie zahlen, um Leistung zu erzielen. Für Code mit Ausdrücken mit booleschem Wert ist die Typensicherheit (wenn Sie weniger und damit impliziten Code schreiben ) von entscheidender Bedeutung, z.

Yauhen Yakimovich
quelle
16

Sie können die Booleschen Konstanten verwenden - Boolean.TRUEund Boolean.FALSEanstelle von 0und 1. Sie können Ihre Variable als Typ erstellen, booleanwenn Sie nach einem Grundelement suchen. Auf diese Weise müssen Sie keine neuen BooleanObjekte erstellen .

Kühle Bohnen
quelle
3

Grundsätzlich stellen Boolesche Werte einen primitiven Datentyp dar, wobei Boolesche Werte einen Referenzdatentyp darstellen. Diese Geschichte wird gestartet, wenn Java rein objektorientiert werden möchte. Es wird ein Wrapper-Klassenkonzept bereitgestellt, um die Verwendung des primitiven Datentyps zu überwinden.

boolean b1;
Boolean b2;

b1und b2sind nicht gleich.

Sachin Jadhav
quelle
3

Eine Beobachtung: (obwohl dies als Nebenwirkung gedacht werden kann)

Boolescher Wert als Primitiv kann entweder Ja oder Nein sagen.

Boolean ist ein Objekt (es kann sich entweder auf Ja oder Nein oder auf 'Weiß nicht' beziehen, dh auf Null).

Sudip Bhandari
quelle
1

Sie können Boolean / Boolean verwenden. Einfachheit ist der richtige Weg. Wenn Sie keine bestimmte API (Sammlungen, Streams usw.) benötigen und nicht vorhersehen, dass Sie sie benötigen, verwenden Sie eine primitive Version davon (Boolescher Wert).

  1. Mit Grundelementen garantieren Sie, dass Sie keine Nullwerte übergeben.
    Sie werden nicht in solche Fallen fallen. Der folgende Code löst eine NullPointerException aus (von: Booleschen Werten, bedingten Operatoren und 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. Verwenden Sie Boolean, wenn Sie ein Objekt benötigen, z.

    • Strom von Booleschen,
    • Optional
    • Sammlungen von Booleschen
Witold Kaczurba
quelle