2010-04-08 9 views
5

(Für die Zwecke dieser Frage, lassen Sie uns, dass man davon ausgehen, ist absichtlich nicht automatisch (un) Boxen, entweder weil ein Pre-Java 1.5-Code zu schreiben, oder weil man das autounboxing fühlt macht es zu einfach NullPointerException s zu erstellen . Warum sollte man die öffentlichen Konstruktoren für Boolesche und ähnliche unveränderliche Klassen verwenden?

Boolean Nehmen wir zum Beispiel

). Die Dokumentation für den Boolean(boolean) Konstruktor sagt:

Hinweis: Es ist selten angemessen, diesen Konstruktor zu verwenden. Es sei denn, eine neue Instanz erforderlich ist, valueOf(boolean) die statische Fabrik ist in der Regel eine bessere Wahl. Es wird wahrscheinlich deutlich bessere Raum und Zeit Leistung erbringen.

Meine Frage ist, warum sollten Sie jemals eine neue Instanz in erster Linie zu bekommen? Es scheint, dass die Dinge einfacher wären, wenn solche Konstruktoren privat wären. Zum Beispiel, wenn sie waren, konnte schreiben Sie dies ohne Gefahr (auch wenn myBoolean waren null):

if (myBoolean == Boolean.TRUE) 

Es wäre sicher, weil alle wahr Booleans Verweise auf Boolean.TRUE sein würde und alle falsch Booleans würde Referenzen sein zu Boolean.FALSE. Aber weil die Konstrukteure öffentlich sind, jemand sie verwendet haben, was bedeutet, dass Sie diese stattdessen schreiben:

if (Boolean.TRUE.equals(myBoolean)) 

aber wo es wirklich schlimm wird, wenn Sie wollen zwei Booleans für Gleichheit überprüfen. Etwas wie folgt aus:

if (myBooleanA == myBooleanB) 

... wird dies:

if (
    myBooleanA == myBooleanB || 
    (myBooleanA != null && myBooleanA.equals(myBooleanB)) 
) 

UPDATE: Mit der Veröffentlichung von Java 7, macht java.util.Objects dies einfacher konstruieren möglich:

if (Objects.equals(myBooleanA, myBooleanB)) 

Ich kann mir keinen Grund vorstellen, getrennte Instanzen dieser Objekte zu haben, was zwingender ist, als den obigen Unsinn nicht zu tun. Was sagst du?

+0

Sie haben diesen letzten Codeblock falsch. Entweder 'a == null? b == null: a.equals (b) 'oder' a == b || (a! = null && a.equals (b)) '. Oder 'Objects.eq (a, b)'. –

+0

Sie haben Recht. Ich habe es in 'a == b || geändert (a! = null && a.equals (b)) '. –

Antwort

5

Die zwischengespeicherten Werte sind nie Müll gesammelt, so dass die Konstrukteure verwenden, wenn Sie sie mögen, dass so weich/schwacher Verweis verwenden, so dass es Müll sowieso gesammelt werden kann, wann immer erforderlich. Das gleiche gilt für , Integer#valueOf() und Konsorten mit Werten innerhalb zwischenspeicherbar Bereichen.

eine Referenz Suche in Eclipse lernt mich tun, dass jeder unter java.lang.Thread verwendet new Boolean() als Soft-Referenz basierten Cache, ist es auch (in isCCLOverridden() Methode) explizit kommentiert:

/* 
* Note: only new Boolean instances (i.e., not Boolean.TRUE or 
* Boolean.FALSE) must be used as cache values, otherwise cache 
* entry will pin associated class. 
*/ 
-1

wurden Diese Objekttypen benötigt, da die Die Collection-Klasse akzeptiert nur Objekte, daher können Sie die nativen Typen nicht verwenden.

Dies führte den Designfehler Sie sprechen und daher eingeführt Autoboxing.

EDIT

Und die Konstrukteure sind öffentlich, weil sie immer öffentlich waren. Vor der Welt des Autoboxierens in sehr schlechtem Code wollten Sie new Integer(0) != new Integer(0), um wahr zu sein. Es war ein Fehler mehr als alles andere des ursprünglichen Designs, aber da es ein Teil der öffentlichen Schnittstelle ist, wollen sie jetzt nicht alten Code brechen.

Ich wette, sie könnten es jetzt ablehnen und die meisten Leute wären damit einverstanden, da Autoboxen einfach funktioniert.

1

Die Konstrukteure wegen der Rückwärtskompatibilität Öffentlichkeit ... .valueOf() wurde nur in Java hinzugefügt 1.4 ...

auch einen Booleschen als Tri-State-Variable in Ihrem Beispiel (null/TRUE mit/FALSE) ist wahrscheinlich eine schlechte Idee - besser, eine Enum (UNKNOWN, TRUE, FALSE) zu verwenden, oder wenn Null ist kein gültiger Wert, überprüfen Sie es, und manuell für das Testen der Gleichheit entpacken.

+0

In Bezug auf Booleans als Tri-Staaten: Ich stimme zu, Enums sind vorzuziehen, aber das ist eher eine defensive Programmierung Sache; d. h. den Fall behandeln, in dem jemand Ihnen eine Null gibt, wenn Sie nur WAHR oder FALSCH erwartet haben. (Dies ist der genaue Grund, warum ich das Auto-Boxen für gefährlich halte; es macht es zu einfach, den Null-Fall zu ignorieren, wenn Sie Objekte wie Primitive behandeln.) –

Verwandte Themen