Что ж, мотивация (обратная совместимость) является как преимуществом, так и недостатком. Это невыгодно, потому что мы все предпочли бы иметь типы reifiable, но цена была высока. Рассмотрим варианты дизайна в C #. У них есть типы reifiable, но теперь у них есть дубликаты API. Итак, представьте Java API, где у нас также были дублированные API для каждого параметризованного класса. Теперь представьте, что вы переносите тысячи строк кода из устаревших классов в новые универсальные классы. Теперь, кто бы не считал дубликаты API недостатками? Но эй, у них есть reifiable типы!
Итак, основной мотивацией была «эволюция, а не революция». И логически, каждое решение имеет компромиссы.
Помимо других упомянутых недостатков, мы могли бы также добавить тот факт, что стирание типов может быть трудно рассуждать во время компиляции, так как не очевидно, что определенные типы будут удалены, и это приводит к очень странным и трудным для поиска ошибкам.
Существование методов моста (этот синтаксически сгенерированный методы компилятора для сохранения двоичной совместимости) также может рассматриваться как недостаток. И это может быть одной из причин ошибок, о которых я упоминал в предыдущем абзаце.
Основные недостатки вытекают из уже очевидного факта, что для универсальных типов существует один класс, а не несколько классов. В качестве другого примера рассмотрим, что перегрузка метода с таким же универсальным классом завершается неудачно в Java:
public void doSomething(List<One>);
public void doSomething(List<Two>);
Кое-что, что может быть замечено как недостаток reifiable типов (по крайней мере в C #), является фактом, что они вызывают взрыв кода . Например List<int>, один класс, а List<double>другой - совершенно другой, так как это List<string>и a List<MyType>. Таким образом, классы должны быть определены во время выполнения, вызывая взрыв классов и потребляя ценные ресурсы, пока они генерируются.
Что касается того факта, что невозможно определить new T()в Java, упомянутого в другом ответе, также интересно учитывать, что это не только вопрос стирания типа. Это также требует существования конструктора по умолчанию, поэтому C # требует для этого «нового ограничения». (См. Почему новый T () невозможен в Java , автор Алекс Бакли).
Ts вы получаете только одну копиюClass<T>кода для всехTs; плюс дополнительная копия для каждого фактически используемого типа значенияT.