Ich habe Neal Gafters Blog zu diesem Thema gelesen und bin in einigen Punkten immer noch unklar.
Warum ist es angesichts des aktuellen Status von Java, der JVM und der vorhandenen Sammlungs-API nicht möglich, Implementierungen der Sammlungs-API zu erstellen, bei denen Typinformationen erhalten bleiben? Könnten diese nicht die vorhandenen Implementierungen in einer zukünftigen Version von Java so ersetzen, dass die Abwärtskompatibilität erhalten bleibt?
Als Beispiel:
List<T> list = REIList<T>(T.Class);
Wo REIList so etwas ist:
public REIList<T>() implements List {
private Object o;
private Class klass;
public REIList(Object o) {
this.o = o;
klass = o.getClass();
}
... the rest of the list implementation ...
Die Methoden verwenden Object o und Class klass, um die Typinformationen abzurufen.
Warum erfordert das Beibehalten allgemeiner Klasseninformationen Sprachänderungen und nicht nur eine Änderung der JVM-Implementierung?
Was verstehe ich nicht?
Entgegen der Meinung der meisten Java-Entwickler ist es möglich, Informationen vom Typ der Kompilierungszeit beizubehalten und diese Informationen zur Laufzeit abzurufen, obwohl dies sehr eingeschränkt ist. Mit anderen Worten: Java bietet reified Generics auf sehr eingeschränkte Weise .
In Bezug auf die Art der Löschung
Beachten Sie, dass dem Compiler zur Kompilierungszeit vollständige Typinformationen zur Verfügung stehen. Diese Informationen werden jedoch im Allgemeinen absichtlich gelöscht, wenn der Binärcode generiert wird. Dies wird als Typlöschung bezeichnet . Dies geschieht aufgrund von Kompatibilitätsproblemen auf diese Weise: Die Absicht der Sprachentwickler bestand darin, vollständige Quellcodekompatibilität und vollständige Binärcodekompatibilität zwischen Versionen der Plattform bereitzustellen. Wenn es anders implementiert wäre, müssten Sie Ihre Legacy-Anwendungen neu kompilieren, wenn Sie auf neuere Versionen der Plattform migrieren. So wie es gemacht wurde, bleiben alle Methodensignaturen erhalten (Quellcode-Kompatibilität) und Sie müssen nichts neu kompilieren (Binärkompatibilität).
In Bezug auf reified Generics in Java
Wenn Sie Informationen zum Typ der Kompilierungszeit beibehalten müssen, müssen Sie anonyme Klassen verwenden. Der Punkt ist: Im ganz besonderen Fall anonymer Klassen ist es möglich, zur Laufzeit vollständige Informationen zum Typ der Kompilierungszeit abzurufen, was mit anderen Worten bedeutet: reifizierte Generika.
Ich habe einen Artikel zu diesem Thema geschrieben:
http://rgomes-info.blogspot.co.uk/2013/12/using-typetokens-to-retrieve-generic.html
In dem Artikel beschreibe ich, wie unsere Benutzer auf die Technik reagiert haben. Kurz gesagt, dies ist ein obskures Thema, und die Technik (oder das Muster, wenn Sie es vorziehen) erscheint den meisten Java-Entwicklern fremd.
Beispielcode
Der Artikel, den ich oben erwähnt habe, enthält Links zum Quellcode, der die Idee ausübt.
quelle
final K k1 = new K<java.lang.Double>() {};
ist genau das gleiche wie die lokale Klasseclass Foo extends K<java.lang.Double> {}; final K k1 = new Foo();
IIRC (und basierend auf dem Link) sind Java-Generika nur syntaktischer Zucker für die vorhandene Technik, eine Objektsammlung zu verwenden und hin und her zu werfen. Die Verwendung der Java-Generika ist sicherer und einfacher, da der Compiler die Überprüfungen für Sie durchführen kann, um sicherzustellen , dass Sie die Sicherheit vom Typ zur Kompilierungszeit gewährleisten. Die Laufzeit ist jedoch ein ganz anderes Problem.
.NET-Generika hingegen erstellen tatsächlich neue Typen - a
List<String>
in C # ist ein anderer Typ als aList<Int>
. In Java sind sie unter dem Deckmantel dasselbe - aList<Object>
. Dies bedeutet, dass Sie, wenn Sie jeweils eine haben, diese zur Laufzeit nicht ansehen und sehen können, als was sie deklariert wurden - nur was sie jetzt sind.Die reifizierten Generika würden dies ändern und Java-Entwicklern die gleichen Funktionen bieten, die jetzt in .NET vorhanden sind.
quelle
Ich bin kein Experte auf diesem Gebiet, aber so wie ich es verstehe, gehen die Typinformationen beim Kompilieren verloren. Anders als in C ++ verwendet Java kein Vorlagensystem, die Typensicherheit wird vollständig durch den Compiler erreicht. Zur Laufzeit ist eine Liste eigentlich immer eine Liste.
Meiner Meinung nach ist eine Änderung der Sprachspezifikation erforderlich, da die Typinformationen der JVM nicht zur Verfügung stehen, weil sie nicht vorhanden sind .
quelle