Java-Sammlungen speichern nur Objekte, keine primitiven Typen. Wir können jedoch die Wrapper-Klassen speichern.
Warum diese Einschränkung?
java
collections
types
primitive-types
JavaUser
quelle
quelle
class
, sondern durch die JVM. Die Anweisungint i = 1
definiert einen Zeiger auf die Singleton-Instanz des Objekts, dieint
in der JVM definiert ist , und setzt auf den Wert1
, der irgendwo in der JVM definiert ist. Ja, Zeiger in Java - dies wird nur durch die Sprachimplementierung von Ihnen abstrahiert. Grundelemente können nicht als Generika verwendet werden, da die Sprache voraussagt, dass alle generischen Typen vom Supertyp sein müssenObject
- daher wirdA<?>
zurA<Object>
Laufzeit kompiliert .Antworten:
Es war eine Java-Entwurfsentscheidung, die einige als Fehler betrachten. Container möchten, dass Objekte und Grundelemente nicht von Object abgeleitet werden.
Dies ist ein Ort, den .NET-Designer von der JVM gelernt und Werttypen und Generika so implementiert haben, dass das Boxen in vielen Fällen entfällt. In CLR können generische Container Werttypen als Teil der zugrunde liegenden Container-Struktur speichern.
Java hat sich dafür entschieden, generische Unterstützung zu 100% im Compiler ohne Unterstützung durch die JVM hinzuzufügen. Die JVM, die das ist, was sie ist, unterstützt kein "Nicht-Objekt" -Objekt. Mit Java-Generika können Sie so tun, als gäbe es keinen Wrapper, aber Sie zahlen trotzdem den Leistungspreis für das Boxen. Dies ist für bestimmte Programmklassen WICHTIG.
Boxen ist ein technischer Kompromiss, und ich denke, es handelt sich um Implementierungsdetails, die in die Sprache gelangen. Autoboxing ist ein guter syntaktischer Zucker, aber immer noch ein Leistungsverlust. Wenn überhaupt, möchte ich, dass der Compiler mich warnt, wenn er Autoboxen erstellt. (Soweit ich weiß, habe ich diese Antwort jetzt 2010 geschrieben).
Eine gute Erklärung zu SO über das Boxen: Warum benötigen einige Sprachen Boxen und Unboxen?
Und Kritik an Java-Generika: Warum behaupten manche, dass Javas Implementierung von Generika schlecht ist?
Zu Javas Verteidigung ist es leicht, zurückzublicken und zu kritisieren. Die JVM hat den Test der Zeit überstanden und ist in vielerlei Hinsicht ein gutes Design.
quelle
Object.ReferenceEquals
Referenzen vom Typ zu übergeben,Object
die Ganzzahlen in Boxen identifizieren, aber es sollte nicht legal sein einen ganzzahligen Wert übergeben]. Javas Auto-Unboxing ist meiner Meinung nach einfach nur böse.Erleichtert die Implementierung. Da Java-Grundelemente nicht als Objekte betrachtet werden, müssen Sie für jedes dieser Grundelemente eine separate Auflistungsklasse erstellen (kein gemeinsam zu verwendender Vorlagencode).
Sie können dies natürlich nur unter GNU Trove , Apache Commons Primitives oder HPPC tun .
Wenn Sie nicht über wirklich große Sammlungen verfügen, ist der Aufwand für die Wrapper für die Benutzer nicht wichtig genug (und wenn Sie über wirklich große primitive Sammlungen verfügen, möchten Sie möglicherweise die Mühe aufwenden, eine spezielle Datenstruktur für sie zu verwenden / aufzubauen ).
quelle
Es ist eine Kombination aus zwei Fakten:
int
ist keinObject
)List<?>
ist aList<Object>
zur Laufzeit wirklich a ).Da beide zutreffen, können generische Java-Sammlungen primitive Typen nicht direkt speichern. Der Einfachheit halber wird Autoboxing eingeführt, damit primitive Typen automatisch als Referenztypen eingerahmt werden können. Machen Sie keinen Fehler, die Sammlungen speichern trotzdem Objektreferenzen.
Könnte dies vermieden worden sein? Vielleicht.
int
istObject
, werden Box-Typen überhaupt nicht benötigt.quelle
Es gibt das Konzept des Auto-Boxing und des Auto-Unboxing. Wenn Sie versuchen, ein
int
in einem zu speichern,List<Integer>
konvertiert der Java-Compiler es automatisch in einInteger
.quelle
Es ist nicht wirklich eine Einschränkung, oder?
Überlegen Sie, ob Sie eine Sammlung erstellen möchten, in der primitive Werte gespeichert sind. Wie würden Sie eine Sammlung schreiben, die entweder int, float oder char speichern kann? Höchstwahrscheinlich werden Sie mehrere Sammlungen haben, daher benötigen Sie eine Intlist und eine Charlist usw.
Wenn Sie beim Schreiben einer Auflistungsklasse die objektorientierte Natur von Java nutzen, können Sie jedes Objekt speichern, sodass Sie nur eine Auflistungsklasse benötigen. Diese Idee, der Polymorphismus, ist sehr mächtig und vereinfacht das Design von Bibliotheken erheblich.
quelle
Ich denke, wir könnten Fortschritte in diesem Bereich im JDK sehen, möglicherweise in Java 10 basierend auf diesem JEP - http://openjdk.java.net/jeps/218 .
Wenn Sie heute Boxprimitive in Sammlungen vermeiden möchten, gibt es mehrere Alternativen von Drittanbietern. Zusätzlich zu den zuvor erwähnten Optionen von Drittanbietern gibt es auch Eclipse Collections , FastUtil und Koloboke .
Ein Vergleich primitiver Karten wurde vor einiger Zeit auch mit dem Titel veröffentlicht: Große HashMap-Übersicht: JDK, FastUtil, Goldman Sachs, HPPC, Koloboke, Trove . Die Bibliothek der GS-Sammlungen (Goldman Sachs) wurde auf die Eclipse Foundation migriert und heißt jetzt Eclipse-Sammlungen.
quelle
Der Hauptgrund ist die Java-Designstrategie. ++ 1) Sammlungen erfordern Objekte zur Manipulation und Grundelemente werden nicht vom Objekt abgeleitet, daher kann dies der andere Grund sein. 2) Primitive Java-Datentypen sind beispielsweise keine Referenztypen. int ist kein Objekt.
Überwinden:-
Wir haben ein Konzept von Auto-Boxing und Auto-Unboxing. Wenn Sie also versuchen, primitive Datentypen zu speichern, konvertiert der Compiler diese automatisch in ein Objekt dieser primitiven Datenklasse.
quelle