Ich sehe, dass Java Boolean (Klasse) vs Boolean (primitiv) hat. Ebenso gibt es eine Ganzzahl (Klasse) vs int (Primitiv). Was ist die beste Vorgehensweise bei der Verwendung der primitiven Version gegenüber der Klasse? Sollte ich grundsätzlich immer die Klassenversion verwenden, es sei denn, ich habe einen bestimmten (Performance-?) Grund, dies nicht zu tun? Was ist die gebräuchlichste, akzeptierte Art, die einzelnen zu verwenden?
54
Antworten:
In Punkt 5 von Effective Java sagt Joshua Bloch
Eine gute Verwendung für Klassen ist die Verwendung als generische Typen (einschließlich Auflistungsklassen wie Listen und Maps) oder die Umwandlung in einen anderen Typ ohne implizites Casting (z. B.
Integer
class has methodsdoubleValue()
oderbyteValue()
.Edit: Joshua Blochs Grund ist:
quelle
Die Standardpraxis besteht darin, mit den Primitiven zu arbeiten, es sei denn, Sie haben es mit Generika zu tun (achten Sie darauf, dass Sie auf Autoboxing und Unboxing achten !).
Es gibt eine Reihe von guten Gründen, der Konvention zu folgen:
1. Sie vermeiden einfache Fehler:
Es gibt einige subtile, nicht intuitive Fälle, die Anfänger häufig herausfordern. Sogar erfahrene Programmierer geraten aus dem Ruder und machen manchmal diese Fehler (hoffentlich wird dies von einem Fluch gefolgt, wenn sie den Code debuggen und den Fehler finden!).
Der häufigste Fehler ist die Verwendung von
a == b
anstelle vona.equals(b)
. Die Leute sind es gewohnt,a == b
mit Primitiven umzugehen, so dass dies mit den Objekt-Wrappern problemlos möglich ist.2. Lesbarkeit:
Betrachten Sie die folgenden zwei Beispiele. Die meisten Leute würden sagen, die zweite ist besser lesbar.
3. Leistung:
Tatsache ist , es ist langsamer , den Object - Wrapper für Primitive zu verwenden , als nur die Grundelemente verwenden. Sie addieren die Kosten für Objektinstanziierung, Methodenaufrufe usw. zu den Dingen, die Sie überall verwenden .
Knuths Zitat "... sagt in 97% der Fälle: Vorzeitige Optimierung ist die Wurzel allen Übels" trifft hier nicht wirklich zu. Er sprach von Optimierungen, die den Code (oder das System) komplizierter machen - wenn Sie Punkt 2 zustimmen, ist dies eine Optimierung, die den Code weniger kompliziert macht!
4. Es ist die Konvention:
Wenn Sie für 99% der anderen Java-Programmierer eine andere Stilauswahl treffen, gibt es zwei Nachteile:
Normalerweise würde ich einige Kontrapunkte auflisten, aber ich kann mir ehrlich gesagt keine guten Gründe vorstellen, hier nicht zur Convention zu gehen!
quelle
==
. Objekte sollten mit verglichen werdenequals()
.equals()
... verglichen werden sollen . Sie umgehen dies, damit der Vergleich von Objekten mit zu==
den erwarteten Ergebnissen führt.equals()
zum zweiten Code-Snippet hinzugefügt und meine Stimme geändert.Normalerweise gehe ich mit den Primitiven. Eine Besonderheit bei der Verwendung von Klassen wie
Integer
undBoolean
ist jedoch die Möglichkeit,null
diese Variablen zuzuweisen. Dies bedeutet natürlich, dass Sie dienull
ganze Zeit Prüfungen durchführen müssen, aber immer noch besser, um eine NullPointerException zu erhalten, als logische Fehler zu haben, weil einigeint
oderboolean
Variablen verwendet werden, die nicht korrekt initialisiert wurden.Natürlich, da 8 Java können Sie (und wahrscheinlich sollte) noch einen Schritt weiter gehen und statt zB
Integer
könnten SieOptional<Integer>
für Variablen , die keinen Wert haben könnten oder könnten.Außerdem wird die Möglichkeit eingeführt
null
, diesen Variablen einen " unbekannten " oder " Platzhalter " -Wert zuzuweisen . Dies kann in bestimmten Situationen nützlich sein, beispielsweise in Ternary Logic . Oder Sie möchten möglicherweise überprüfen, ob ein bestimmtes Objekt mit einer Vorlage übereinstimmt. In diesem Fall können Sienull
Variablen in der Vorlage verwenden, die einen beliebigen Wert im Objekt haben können.quelle
null
Standardeinstellungen zuzuweisen . Im Gegenteil: Es ist besser, wenn Sie die Variable überhaupt nicht "initialisieren". Durch das Festlegen eines Standardwerts wirdnull
der Compiler heruntergefahren, es wird jedoch auch verhindert, dass die fehlende sinnvolle Zuordnung auf allen Codepfaden erkannt wird. Somit wird ein Fehler, den der Compiler möglicherweise abgefangen hat, zur Laufzeit weitergeleitet.0.0
, oder-1
oderInteger.MAX_VALUE
oder setzenFalse
, aber am Ende wissen Sie nicht, ob dies der Standardwert oder ein tatsächlicher Wert ist, der dieser Variablen zugewiesen wurde. In Fällen, in denen dies wichtig ist, ist dernull
Wert möglicherweise klarer.null
s haben eine ganze Reihe von Problemen, einschließlich Null-Paranoia.) Innerhalb einer Funktion weist eine Variable, die zum Zeitpunkt der Verwendung möglicherweise tatsächlich nicht initialisiert wurde, in der Regel auf nicht abgedeckte Fälle hin. (Bestimmte Zuweisungsanalysen sind vereinfachend, so dass Fehlalarme möglich sind. Sie können sie jedoch häufig beheben, indem Sie die Logik vereinfachen.)Mit den Worten des Laien:
Sie verwenden die Wrapper, wenn Sie Dinge zu Sammlungen hinzufügen müssen.
Sammlungen können keine Grundelemente enthalten.
quelle
Java bietet Autoboxing, wie m3th0dman hervorhob. Wenn Sie auf der niedrigstmöglichen Ebene nachdenken, werden Sie feststellen, dass das automatische Aktivieren oder Deaktivieren eines primitiven Werts Taktzyklen impliziert, die für einige Aufgaben erforderlich sind, die Sie nicht benötigen, wenn Sie mit systemeigenen Datentypen in Ihrer Anwendung arbeiten.
In der Regel sollten Sie nach Möglichkeit versuchen, native Datentypen zu verwenden.
quelle