it-swarm.com.de

Warum können Java Collections keine Primitives-Typen direkt speichern?

Java-Sammlungen speichern nur Objekte und keine primitiven Typen. Die Wrapper-Klassen können jedoch gespeichert werden.

Warum diese Einschränkung?

102
JavaUser

Es war eine Entscheidung für das Java-Design, und einige werden für einen Fehler gehalten. Container möchten, dass Objekte und Primitive nicht von Object abgeleitet werden.

Dies ist ein Ort, den .NET-Designer von der JVM gelernt haben, und Werttypen und Generika implementiert haben, so dass das Boxen in vielen Fällen entfällt. In CLR können generische Container Werttypen als Teil der zugrunde liegenden Containerstruktur speichern.

Java entschied sich für die generische Unterstützung im Compiler zu 100% ohne Unterstützung der JVM. Die JVM unterstützt das Objekt "Nicht-Objekt" nicht. Mit Java-Generics können Sie so tun, als gäbe es keinen Wrapper, aber Sie zahlen trotzdem den Leistungspreis des Boxens. Dies ist WICHTIG für bestimmte Programmklassen.

Boxen ist ein technischer Kompromiss, und ich glaube, es sind Details der Implementierung, die in die Sprache gelangen. Autoboxing ist Nizza syntaktischer Zucker, ist aber immer noch eine Leistungsstrafe. Wenn überhaupt, möchte ich, dass der Compiler mich bei automatischen Autoboxen warnt. (Für alles was ich weiß, kann ich jetzt schreiben, ich habe diese Antwort 2010 geschrieben).

Eine gute Erklärung zu SO über Boxen: Warum benötigen einige Sprachen Boxen und Unboxing?

Und Kritik an Java-Generics: Warum behaupten manche, dass Javas Implementierung von Generics schlecht ist?

In Javas Verteidigung ist es leicht, zurückzublicken und zu kritisieren. Die JVM hat den Test der Zeit bestanden und ist in vielerlei Hinsicht ein gutes Design.

83
codenheim

Erleichtert die Implementierung. Da Java-Grundelemente nicht als Objekte betrachtet werden, müssen Sie für jedes dieser Grundelemente eine separate Auflistungsklasse erstellen (kein Vorlagencode für die Freigabe).

Sie können das natürlich nur sehen - GNU Trove , Apache Commons Primitives oder HPPC .

Wenn Sie nicht über sehr große Sammlungen verfügen, ist der Aufwand für die Wrapper nicht wichtig für die Menschen, die sich darum kümmern (und wenn Sie über wirklich große primitive Sammlungen verfügen, möchten Sie möglicherweise die Verwendung einer speziellen Datenstruktur für sie untersuchen ).

15
Thilo

Es ist eine Kombination aus zwei Fakten:

  • Java-Grundtypen sind keine Referenztypen (beispielsweise ist eine int keine Object)
  • Java führt Generics unter Verwendung der Typ-Löschung von Referenztypen aus (beispielsweise ist ein List<?> tatsächlich ein List<Object> zur Laufzeit).

Da beide zutreffen, können generische Java-Sammlungen primitive Typen nicht direkt speichern. Zur Vereinfachung wird Autoboxing eingeführt, um Primitivtypen automatisch als Referenztypen zu kennzeichnen. Machen Sie keinen Fehler, die Sammlungen speichern jedoch trotzdem Objektreferenzen.

Könnte das vermieden werden? Vielleicht.

  • Wenn eine int eine Object ist, sind überhaupt keine Box-Typen erforderlich.
  • Wenn Generics nicht mit dem Löschen von Typen ausgeführt werden, könnten Grundelemente für Typparameter verwendet werden.
11

Es gibt das Konzept von Auto-Boxing und Auto-Unboxing. Wenn Sie versuchen, eine int in einem List<Integer> zu speichern, konvertiert der Java-Compiler diese automatisch in eine Integer.

7
Jeremy

Es ist nicht wirklich eine Einschränkung, oder?

Überlegen Sie, ob Sie eine Sammlung mit primitiven Werten erstellen möchten. Wie würden Sie eine Sammlung schreiben, die entweder int, float oder char speichern kann? Es ist sehr wahrscheinlich, dass Sie mehrere Sammlungen haben, also benötigen Sie eine intlist und eine charlist usw.

Die objektorientierte Natur von Java kann beim Schreiben einer Collection-Klasse genutzt werden, da jedes Objekt gespeichert werden kann, sodass nur eine Collection-Klasse benötigt wird. Diese Idee, Polymorphismus, ist sehr mächtig und vereinfacht das Design von Bibliotheken erheblich.

3

Der Hauptgrund ist die Java-Entwurfsstrategie ++ 1) Sammlungen erfordern Objekte zur Bearbeitung, und Grundelemente werden nicht vom Objekt .__ abgeleitet. Dies kann auch der andere Grund sein. 2) Java-Grunddatentypen sind kein Referenztyp für ex. int ist kein Objekt.

Überwinden:-

wir haben ein Konzept für Auto-Boxing und Auto-Unboxing. Wenn Sie versuchen, primitive Datentypen zu speichern, konvertiert Compiler dies automatisch in ein Objekt dieser primitiven Datenklasse.

0
user5693566

Ich denke, wir könnten in diesem Bereich im JDK möglicherweise Fortschritte in Java 10 sehen, basierend auf diesem JEP - http://openjdk.Java.net/jeps/218 .

Wenn Sie heutzutage Boxprimitive in Sammlungen vermeiden möchten, gibt es mehrere Alternativen von Drittanbietern. Neben den zuvor genannten Fremdanbieteroptionen gibt es auch Eclipse Collections , FastUtil und Koloboke .

Ein Vergleich der primitiven Karten wurde vor einiger Zeit auch mit dem Titel veröffentlicht: Large HashMap Übersicht: JDK, FastUtil, Goldman Sachs, HPPC, Koloboke, Trove . Die Bibliothek von GS Collections (Goldman Sachs) wurde zur Eclipse Foundation migriert und ist jetzt Eclipse Collections.

0
Donald Raab