C# против дженериков Java

Я слышал, что Java-реализация Generics не так хороша, как реализация C#. В этом синтаксисе похоже, что не соответствует стандартам реализации Java, или это религиозная точка зрения?

похоже, этот вопрос уже задавали - stackoverflow.com/questions/31693/differences-in-generics#31‌ 866

serg10 10.12.2008 16:51

Комплексное сравнение здесь, с некоторыми ссылками.

Strelok 10.12.2008 07:15
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
124
2
50 823
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Разница заключается в дизайнерском решении Microsoft и Sun.

Дженерики в Java реализуется компилятором через стирание типа, что означает, что проверка типа происходит во время компиляции, а информация о типе удаляется. Этот подход был использован для сохранения совместимости устаревшего кода с новым кодом, использующим обобщения:

Из Руководства по Java, Обобщения: Стирание типа:

When a generic type is instantiated, the compiler translates those types by a technique called type erasure — a process where the compiler removes all information related to type parameters and type arguments within a class or method. Type erasure enables Java applications that use generics to maintain binary compatibility with Java libraries and applications that were created before generics.

Однако с дженерики в C# (.NET) компилятор не стирает типы, и проверки типов выполняются во время выполнения. Это имеет свои преимущества в том, что информация о типе сохраняется в скомпилированном коде.

Из Википедии:

This design choice is leveraged to provide additional functionality, such as allowing reflection with preservation of generic types, as well as alleviating some of the limitations of erasure (such as being unable to create generic arrays). This also means that there is no performance hit from runtime casts and normally expensive boxing conversions.

Вместо того, чтобы говорить «дженерики .NET лучше, чем дженерики Java», следует изучить разницу в подходах к реализации дженериков. В Java кажется, что сохранение совместимости было высоким приоритетом, тогда как в .NET (когда он был представлен в версии 2.0) реализация всех преимуществ использования дженериков была более приоритетной.

@Tom Что означает "Иммунитет от анализа"?

halfbit 15.08.2014 18:15

Это означает, что да, вы можете сказать: «Дженерики .NET лучше, чем дженерики Java». Java должна была принять тот же подход, чтобы внести критические изменения и правильно реализовать дженерики еще в прошлом, когда у них была возможность сделать это.

Mike 15.09.2014 17:20

«Обратная совместимость» неверна, они оба обратно совместимы. Это было сделано для «совместимости миграции».

kervin 05.04.2015 04:37
Ответ принят как подходящий

ссылка Стрелокси отлично справляется с устранением различий. Краткое и грязное резюме ...

С точки зрения синтаксиса и использования. Синтаксис языков примерно одинаков. Несколько причуд здесь и там (особенно в ограничениях). Но в основном, если вы можете прочитать один, вы, вероятно, сможете прочитать / использовать другой.

Однако самая большая разница заключается в реализации.

Java использует понятие стирания типов для реализации универсальных шаблонов. Короче говоря, базовые скомпилированные классы на самом деле не являются универсальными. Они компилируются до Object и преобразуются. По сути, универсальные шаблоны Java являются артефактом времени компиляции и могут быть легко разрушены во время выполнения.

C#, с другой стороны, благодаря CLR реализует универсальные шаблоны вплоть до байтового кода. В CLR было внесено несколько критических изменений для поддержки дженериков в 2.0. Преимущества заключаются в улучшении производительности, глубокой проверке безопасности типов и отражении.

Опять же, предоставленный связь имеет гораздо более глубокую разбивку, я рекомендую вам прочитать

Я читал ссылку на ваш Стрелок, интервью Андерса Хейлсберга и Сообщение блога Эрика Липперта. Но я все еще не могу этого понять - как C# не выполняет стирание типа Ссылочные типы а также используют один и тот же код IL? Не могли бы вы немного рассказать об этом?

Alexander Malakhov 30.05.2012 13:46

@AlexanderMalakhov все ссылочные типы имеют размер слова в сборке и могут управляться одними и теми же инструкциями, следовательно, они могут использовать один и тот же шаблон сборки. В чем, по вашему мнению, они будут отличаться?

JaredPar 30.05.2012 21:18

Думаю, Java делает то же самое. Тогда где информация о типе? Как, например, может работать рефлексия?

Alexander Malakhov 31.05.2012 05:17

@AlexanderMalakhov каждый экземпляр по-прежнему имеет уникальный тип объекта, просто все слоты метода указывают на одну и ту же реализацию.

JaredPar 31.05.2012 05:18

Вроде как на java 10 поменяют :)

Ced 30.06.2016 06:34

для java 10 таких планов нет. Интересно, насколько он производительнее!

Dragonborn 05.02.2017 21:28

Также нашел разговор это с Андерсом Хейлсбергом, который тоже может быть интересным. Подытоживая замечания, сделанные Андерсом Хейлсбергом, с некоторыми дополнительными замечаниями: Дженерики Java были созданы для максимальной совместимости с существующей JVM., который привел к нескольким странным вещам по сравнению с реализацией, которую вы видите на C#:

  • Стирание типа заставляет реализацию представлять каждое общее параметризованное значение как Object. В то время как компилятор обеспечивает автоматическое преобразование между Object и более конкретным типом, это не снимает негативного влияния типов забросов и бокса на работоспособность (например, Object приводится к конкретному типу MyClass или int должен быть упакован в Integer, что было бы еще более серьезным для C# /. NET, если бы они следовали подходу стирания типов из-за в определяемые пользователем типы значений). Как сказал Андерс: «вы не получаете никакой эффективности выполнения» (в C# включены обобщенные дженерики)

  • Стирание типа делает информацию доступной во время компиляции, недоступной во время выполнения. То, что раньше было List<Integer>, становится просто List без возможности восстановления параметра универсального типа во время выполнения. Это затрудняет построение сценариев отражения или динамической генерации кода на основе универсальных шаблонов Java. Более свежий ТАК ответ показывает способ обойти это через анонимные классы. Но без уловок что-то вроде генерации кода во время выполнения через отражение, которое получает элементы из одного экземпляра коллекции и помещает их в другой экземпляр коллекции, может дать сбой во время выполнения во время выполнения динамически сгенерированного кода: отражение не помогает отловить несоответствие в List<Double> по сравнению с List<Integer> в эти ситуации.

Но +1 за ответ со ссылкой на Сообщение блога Джонатана Прайора.

Другие вопросы по теме