Warum ist es so, wenn ich versuche, ein Array von ArrayLists zu erstellen: ArrayList<Integer>[] arr=new ArrayList<Integer>[40];
Es liegt ein Fehler vor und Java lässt dies nicht zu?
Gibt es einen Grund für die Implementierung von Generika, Generika in einer beliebigen Sprache oder etwas Willkürlichem in Java?
java
language-design
generics
Jakob Weisblat
quelle
quelle
Antworten:
Dies ist eine der Hauptlücken in Javas Generika. Arrays sind kovariant , was bedeutet, dass ein Array vom Typ
Foo[]
eine Unterklasse vonObject[]
und istParentOfFoo[]
. Vergleichen Sie dies mitList<Foo>
dem, das dieses Verhalten nicht hat.Dies war wichtig, wenn Java keine Generika hatte (bis Java 5), da sonst so etwas wie eine generische Sortierfunktion einfach unmöglich war.
Es hat jedoch dieses knifflige Problem, dass Arrays gerne wissen, um welchen Typ es sich zur Laufzeit handelt . Generika in Java basieren jedoch auf dem Löschen von Typen. Diese beiden Dinge passen überhaupt nicht gut zusammen und hier bekommen wir unser Problem.
Das lange und kurze daran ist, dass in Java 1 kovariante Arrays teilweise die Lücke füllten, die ein Mangel an Generika verursachte. Als sie jedoch versuchten, diese Lücke richtig zu füllen, bedeutete die Abwärtskompatibilität, dass Arrays ziemlich unmöglich zu implementieren waren.
Tatsächlich hat der Typ, der tatsächlich den Rahmen für Generika geschaffen hat, Martin Odersky, hier in einem Interview darüber gesprochen, warum er Scala gemacht hat. (Ziemlich faszinierend, wenn Sie sich überhaupt für Scalas Geschichte interessieren)
quelle
Eigentlich ist es etwas willkürlich.
Das Problem ist, dass es ein Loch im Typsystem zulässt, da
ArrayList<T>[]
es gegossen werden kannObject[]
und Sie dann einArrayList<U>
in das Array einfügen können, woU != T
.Java-Designer haben beschlossen, dieses Loch so eifrig wie möglich zu blockieren, indem sie es
new ArrayList<T>[N]
überhaupt nicht zulassen .Es könnte jedoch auch eingesteckt worden sein, indem das Upcasting von Arrays von Generika nicht zugelassen wurde (ohne eine "ungeprüfte" Warnung).
quelle
Integer
Object[]
String[]
Da das Array kovariant ist und jeder Typ eine Unterklasse des Objekts ist, führt dies aufgrund einer Casting-Ausnahme zu einem Laufzeitfehler. Während das Generikum unveränderlich ist , gibt es einen Compilerfehler aus, wenn es auf dem Typ "Sicherstellen" oder "Typensicher" aufbaut. Wenn der Typ nicht dem Typ entspricht, den es erstellt.
quelle