Kurz gesagt, das wird nicht kompiliert:
%Vor%Liegt es an Problemen mit der Rückwärtskompatibilität oder ist es etwas Grundlegendes im Sprachdesign, das das verhindert?
Die untere Zeile besagt, dass die Klasse, die das Array darstellt, den Komponententyp kennen muss. Daher die Methode für das Klassenobjekt:
%Vor%Also, wenn du es versuchen würdest:
%Vor%Bei der Kompilierung ist es offensichtlich, dass wir den Typ nicht kennen, da es sich um einen generischen Parameter handelt. Zur Laufzeit kennen wir den Typ aufgrund von Typlöschung nicht. So ist das Instanziieren des Arrays unmöglich.
Stellen Sie sich die obige Aussage als gleichwertig vor:
%Vor%Und wegen der Art des Löschens können wir die Klasse von A zur Laufzeit nicht bekommen.
Es wurde gefragt, warum der Compiler nicht auf Object [] oder Number [] oder so etwas reduzieren soll?
Dies liegt daran, dass je nach Komponententyp eine andere Klasse zurückgegeben wird. Also:
%Vor%sind nicht dieselbe Klasse. Insbesondere die Methode "getComponentType ()" für die Klasse würde verschiedene Werte zurückgeben.
Wenn Sie es also auf Object [] anstelle von A [] reduzieren, erhalten Sie tatsächlich nicht etwas vom Typ A [] zurück, sondern Sie erhalten Objekt [] zurück. Object [] kann nicht auf Integer [] übertragen werden und führt zu einer ClassCastException.
Geben Sie löschen ist das Wort, das Sie suchen. Es bedeutet im Grunde, dass die generischen Informationen zur Kompilierungszeit gelöscht werden. Der Hauptgrund dafür ist die Rückwärtskompatibilität. Ältere Programme sollten immer noch auf der neuen Java Virtual Machine laufen.
Dies funktioniert nicht für den gleichen (oder fast den gleichen) Grund, dass new A()
nicht funktionieren kann: Sie erwarten, dass der Compiler den Laufzeittyp von A
kennt, den er eindeutig nicht kennen kann. Dieses würde funktionieren, wenn Java Generics wie C ++ - Templates wären, wo für jede Instantiierung des Templates mit A
neuer Code generiert wird.
In Java ist das Typsystem für Arrays und Generics inkompatibel. Es gibt zwei Hauptbereiche der Diskrepanz: dynamische vs statische Typüberprüfung und Kovarianz .
Generics werden statisch überprüft, das heißt, der Compiler stellt sicher, dass die Typdefinitionen kohärent sind. "Type Erasure" war ein Kompromiss, um die Rückwärtskompatibilität in der JVM zu gewährleisten. Nach der Kompilierung ist die generische Typdefinition nicht mehr verfügbar. Z.B. Liste wird zu Liste.
Im Gegensatz dazu werden Arrays dynamisch typisiert. Betrachten Sie das folgende Beispiel:
%Vor%Kovarianz ist die Vererbungsbeziehung eines Containers basierend auf dem Inhalt. Gegeben sind die Typen A, B und ein Container C, wenn B isAssignableFrom (A) = & gt; C isAssignable C.
Arrays in Java sind im vorherigen Beispiel kovariant, vorausgesetzt, Class<Object>.isAssignableFrom(Class<String>) => Object[] is assignable from String[]
Im Gegensatz dazu sind generische Typen in Java nicht kovariant. Verwenden Sie das gleiche Beispiel:
%Vor%Angesichts der Typlöschung der Generika-Implementierung gehen Typinformationen in der Übersetzung verloren, und daher wäre die dynamische Typprüfung beeinträchtigt, wenn Sie ein Array eines generischen Typs erstellen könnten.
Lesen Sie weiter die Komplikationen und Auswirkungen dieser Probleme: Arrays in Java Generics
Ja, es gibt einen fundamentalen Grund, der darauf hinausläuft, Löschen zu tippen .
Betrachten Sie das folgende Snippet:
%Vor%Verwandte Frage:
Tags und Links java language-design language-details