Warum können Java-Generika nicht in Arrays enthalten sein?

10

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?

Jakob Weisblat
quelle

Antworten:

20

Dies ist eine der Hauptlücken in Javas Generika. Arrays sind kovariant , was bedeutet, dass ein Array vom Typ Foo[]eine Unterklasse von Object[]und ist ParentOfFoo[]. Vergleichen Sie dies mit List<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)

Daniel Gratzer
quelle
3

Gibt es einen Grund für die Implementierung von Generika, Generika in einer beliebigen Sprache oder etwas Willkürlichem in Java?

Eigentlich ist es etwas willkürlich.

Das Problem ist, dass es ein Loch im Typsystem zulässt, da ArrayList<T>[]es gegossen werden kann Object[]und Sie dann ein ArrayList<U>in das Array einfügen können, wo U != 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).

DepressedDaniel
quelle
Diese Antwort wird unterschätzt. Sehr einfach und verwendet Jargon nicht zu vagen Begriffen. Vielen Dank.
Tung Nguyen
Vielleicht möchten Sie IntegerObject[]String[]
näher
-3

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.

Nullcode
quelle