Nun, die Motivation (Abwärtskompatibilität) ist sowohl ein Vorteil als auch ein Nachteil. Es ist ein Nachteil, weil wir alle lieber reifizierbare Typen hätten, aber der zu zahlende Preis war hoch. Berücksichtigen Sie die Entwurfsoptionen in C #. Sie haben reifizierbare Typen, aber jetzt haben sie doppelte APIs. Stellen Sie sich also eine Java-API vor, bei der wir auch doppelte APIs für jede parametrisierte Klasse hatten. Stellen Sie sich nun vor, Sie portieren Tausende von Codezeilen von Legacy-Klassen auf die neuen generischen Klassen. Wer würde doppelte APIs nicht als Nachteil betrachten? Aber hey, sie haben reifizierbare Typen!
Die Hauptmotivation war also "Evolution, nicht Revolution". Und logischerweise hat jede Entscheidung Kompromisse.
Neben den anderen genannten Nachteilen können wir auch die Tatsache hinzufügen, dass das Löschen von Typen zum Zeitpunkt der Kompilierung schwierig zu begründen sein kann, da nicht ersichtlich ist, dass bestimmte Typen entfernt werden, und dies zu sehr seltsamen und schwer zu findenden Fehlern führt.
Die Existenz von Bridge-Methoden (diese vom Compiler syntaktisch generierten Methoden zur Wahrung der Binärkompatibilität) kann ebenfalls als Nachteil angesehen werden. Und dies kann genau einer der Gründe für Fehler sein, die ich im vorherigen Absatz erwähnt habe.
Hauptnachteile ergeben sich aus der bereits offensichtlichen Tatsache, dass es für generische Typen eine einzelne Klasse und nicht mehrere Klassen gibt. Als weiteres Beispiel gilt, dass das Überladen einer Methode mit derselben generischen Klasse in Java fehlschlägt:
public void doSomething(List<One>);
public void doSomething(List<Two>);
Etwas , das als Nachteil reifiable Typen (zumindest in C #) ist die Tatsache , dass sie Ursache gesehen werden könnte Code Explosion . Zum Beispiel List<int>
ist eine Klasse und a List<double>
ist eine andere völlig anders, wie es a List<string>
und a ist List<MyType>
. Daher müssen Klassen zur Laufzeit definiert werden, was zu einer Explosion von Klassen führt und wertvolle Ressourcen verbraucht, während sie generiert werden.
In Anbetracht der Tatsache, dass es nicht möglich ist, ein new T()
in Java zu definieren , was in einer anderen Antwort erwähnt wird, ist es auch interessant zu berücksichtigen, dass dies nicht nur eine Frage der Typlöschung ist. Es erfordert auch die Existenz eines Standardkonstruktors, weshalb C # hierfür eine "neue Einschränkung" erfordert. (Siehe Warum neues T () in Java nicht möglich ist , von Alex Buckley).
T
nur eine Kopie desClass<T>
Codes für alleT
s erhalten. plus eine zusätzliche Kopie für jeden WerttypT
tatsächlich verwendet wird .Der Nachteil der Typlöschung besteht darin, dass Sie zur Laufzeit den Typ des Generikums nicht kennen. Dies bedeutet, dass Sie keine Reflexion auf sie anwenden und sie zur Laufzeit nicht instanziieren können.
In Java können Sie so etwas nicht tun:
Hierfür gibt es eine Problemumgehung, für die jedoch mehr Code erforderlich ist. Der Vorteil ist, wie Sie bereits erwähnt haben, die Abwärtskompatibilität.
quelle
Ein weiterer Vorteil von gelöschten Generika besteht darin, dass verschiedene Sprachen, die mit der JVM kompiliert werden, unterschiedliche Strategien für Generika verwenden, z. B. Scalas Definitionssite gegenüber Javas Use-Site-Kovarianz. Auch Scalas höherwertige Generika wären bei den reifizierten Typen von .Net schwieriger zu unterstützen gewesen, da Scala bei .Net im Wesentlichen das inkompatible Reifizierungsformat von C # ignorierte. Wenn wir Generika in der JVM reifiziert hätten, wären diese reifizierten Generika höchstwahrscheinlich nicht für die Funktionen geeignet, die wir an Scala wirklich mögen, und wir wären mit etwas Suboptimalem festgefahren. Zitat aus Ola Binis Blog ,
Persönlich halte ich die Notwendigkeit, einen
TypeTag
in Scala gebundenen Kontext für widersprüchliche überladene Methoden zu verwenden, nicht für einen Nachteil, da dadurch der Aufwand und die Unflexibilität der Reifizierung von einem globalen (gesamtes Programm und alle möglichen Sprachen) auf eine Verwendungssite pro Sprache verlagert werden Problem, das nur seltener der Fall ist.quelle