Warum sind Generika der zweiten Ebene in Java nicht möglich?

8

Lange Rede kurzer Sinn: Warum ist das Folgende in Java nicht möglich?

%Vor%
  

Hinweis: Ich habe momentan keinen speziellen Anwendungsfall, sondern ich versuche nur zu verstehen, warum das nicht erlaubt ist.

Zuerst dachte ich, weil der Compiler nicht durchsetzen kann, wenn A den generics-Parameter akzeptiert, weil nach dem Kompilieren von A aufgrund des Type-Löschens die Generics nicht mehr vorhanden sind.

Aber wenn das der Fall ist, dann können wir Generika in keiner Klasse verwenden. Also nahm ich den Byte-Code einer generischen Klasse heraus und fand heraus, dass es Metadaten gibt, die sagen, dass sie Generics akzeptiert.

%Vor%

Und ich habe eine schnelle Suche und SO bestätigt kompilierten Code haben Generika verwandte Metadaten auch

Warum erlaubt der Compiler keine Multilevel-Generics?

Wird es ein Problem geben, das zuzulassen? Ist es eine Einschränkung? oder etwas anderes?

    
Codebender 25.07.2015, 13:37
quelle

2 Antworten

7

Nehmen wir an, dass diese Klasse tatsächlich kompiliert:

%Vor%

Dies bedeutet, dass eine richtige Instanziierung der Klasse wäre:

%Vor%

und das Folgende wäre nicht korrekt (da der angegebene Typparameter nicht generisch ist):

%Vor%

Allerdings sollte ein Typparameter nicht als generisch eingeschränkt sein oder nicht - er sollte nur einige Metainformationen über den -Typ enthalten (und wie sich herausstellt, Dies ist der -Typ nach dem Typ-Löschen stattgefunden hat, mit dem er ersetzt werden würde.

Typ-Löschung selbst kann ein anderer möglicher Grund dafür sein, solche Konstruktionen nicht zu erlauben. Lassen Sie uns noch einmal in Betracht ziehen, dass die obige Test -Klasse korrekt definiert wurde und Sie dies hatten:

%Vor%

Beim Typ-Löschen sollte <A<B>> durch Class<Integer> ersetzt werden, aufgrund des Löschens hätten wir jedoch nur Class (obwohl es intern Informationen über den Integer -Typ enthalten würde ) - erwartet ein Class<Integer> , aber die Angabe eines Class sollte nicht korrekt sein.

Danke für die interessante Frage!

    
Konstantin Yovkov 25.07.2015, 14:15
quelle
2

Scala nennt es höher verwandte Typen. Es ist also definitiv eine machbare Abstraktion. Das Hinzufügen zu Java wurde - meines Wissens nach - nie ernsthaft in Betracht gezogen.

Leider kann ich keinen guten Einleitungstext zu Scalas höhergestellten Typen finden. Das Beste, was ich finden kann, ist das Originalpapier Generika einer höheren Art ; Hier ist seine Zusammenfassung:

  

Mit Java 5 und C # 2.0 wurde parametrischer Polymorphismus erster Ordnung in gängigen objektorientierten Programmiersprachen unter dem Namen generics eingeführt. Obwohl die generische Variante erster Ordnung sehr nützlich ist, gibt es auch einige Einschränkungen: Es ist möglich, über einen Typ zu abstrahieren, aber der resultierende Typkonstruktor kann nicht abstrahiert werden. Dies kann zur Code-Duplizierung führen. Wir haben diese Einschränkung in Scala entfernt, indem wir Typkonstruktoren als Typparameter und abstrakte Typelemente zugelassen haben. Dieser Beitrag stellt das Design und die Implementierung des resultierenden Typkonstruktorpolymorphismus vor. Darüber hinaus untersuchen wir, wie dieses Feature mit vorhandenen objektorientierten Konstrukten interagiert und wie es die Sprache ausdrucksstärker macht.

    
Ben Schulz 25.07.2015 20:12
quelle

Tags und Links