2013-07-12 3 views
5

Я понимаю, что причина, по которой в Java есть исходные типы и стирание стилей, заключается в том, что, поскольку в то время были введены генерики, существовали стандартные API-интерфейсы, которые не могли быть родовыми без нарушения существующего кода.Почему Java (но не .NET) неспособна разместить дженерики без необходимости использования сырых типов/типов стирания?

Дженерики были также представлены в .NET в какой-то момент по дороге, но эта функция была реализована таким образом, что она не полагается на сырые типы или стирание типа (и если это так, то это делается так, прозрачный для пользователя). Таким образом, существующие API остались неизменными (например, код в пространстве имен System.Collections) и были введены новые общие API (например, код в пространстве имен System.Collections.Generic).

Так как же Java-генераторы, в отличие от .NET-дженериков, требуют сырых типов/типов стирания?

ответ

8

.Net представил генерики, изменив язык байт-кода, виртуальную машину и JITter, чтобы распознавать общие типы.
Это была огромная работа, которая заняла около двух лет.

Java представил генерики как функцию чисто компиляции с небольшими изменениями времени выполнения (новые метаданные и API отражения).
Это была гораздо более простая задача, и она поддерживала обратную совместимость со старыми временем автономной работы, но работать с ней гораздо более раздражает.

+3

Кроме того. .Net заменил существующие контейнеры родовыми версиями в другом пространстве имен. Код, который хочет использовать их, должен быть перенесен практически сразу. Способ Java позволил им просто сделать существующие контейнеры родовыми, поэтому портирование по частям означает просто случайное подавление и предупреждение. –

+0

@SebastianRedl: Это в основном расширение дженериков, являющихся функцией времени компиляции. – SLaks

+0

Хотя .NET изменил язык байт-кода, я не думаю, что Java обязательно должен был бы сделать это, чтобы универсальные объекты могли знать их тип. Я думаю, было бы возможно, чтобы каждый экземпляр общего объекта содержал одно или несколько полей, сгенерированных компилятором, обозначающее комбинацию типов, с которыми был создан экземпляр экземпляра, и для компилятора сгенерированный код, который, при необходимости, проверял бы такие поля. Я думаю, что большая проблема заключалась бы в том, что если 'ArrayList ' были реализованы как любой тип, отличный от' ArrayList' ... – supercat

3

Солнце особенно стремилось гарантировать обратную совместимость, поскольку была создана большая база программного обеспечения Java. Для этого они считали, что минимальные изменения в JVM были лучшими. Оглядываясь назад, это, по-видимому, не было лучшим решением в долгосрочной перспективе, поскольку это означает, что JVM действительно не понимает дженерики и не может оптимизировать многие избыточные проверки класса.

Oracle по сравнению с тем, что не захотело сменить JVM, и пострадали более серьезные и публичные ошибки esp. для обеспечения безопасности. (Они не означают одно и то же, но можно привести к другому). Тем не менее, Oracle добавила только одну инструкцию в JVM, которую Java даже не использует, в то время как Sun не добавила ее, поэтому она действительно относительна. ;)

Microsoft, с другой стороны, имеет меньшую базу кода для C#, а клиенты более привыкли к значительным, даже нарушая изменения между основными версиями. Это означает боль в краткосрочной перспективе, но может быть лучшим выбором в долгосрочной перспективе. У вас меньше проблем, связанных с исторической причиной.

Вкратце разница не техническая, она более политическая и историческая.

+1

Разница ** чрезвычайно ** техническая. – SLaks

Смежные вопросы