Объясните разницу между шаблонами в C++ и дженериками в Java
24К открытий25К показов
Многие программисты полагают, что шаблоны C++ и дженерики (например в Java) — это одно и то же, ведь их синтаксис похож: в обоих случаях можно написать что-то вроде List<T>
. Чтобы найти различия, давайте разберемся, что такое шаблоны и дженерики, и как они реализуется в каждом из языков.
Дженерики Java связаны с идеей «стирания типов» (type erasure). Эта техника устраняет параметры типов, когда исходный код преобразуется в байткод JVM.
Предположим, что у вас есть Java-код:
Во время компиляции он будет преобразован:
Использование обобщений Java не повлияло на наши возможности, но сделало код более красивым. Поэтому дженерики в Java часто называют «синтаксическим сахаром».
Дженерики сильно отличаются от шаблонов C++. Шаблоны в C++ представляют собой набор макросов, создающих новую копию шаблонного кода для каждого типа. Особенно это заметно на следующем примере: экземпляр MyClass<Foo>
не сможет совместно с MyClass<Bar>
использовать статическую переменную. А два экземпляра MyClass<Foo>
будут совместно использовать статическую переменную.
Чтобы проиллюстрировать этот пример, рассмотрим следующий код:
В Java различные экземпляры MyClass
могут совместно использовать статические переменные, независимо от параметров типа.
Из-за различий в архитектуре дженерики Java и шаблоны C++ имеют множество отличий:
- Шаблоны C++ могут использовать примитивные типы, как, например,
int
, а дженерики Java — нет, они обязаны использоватьInteger
. - Java позволяет указывать ограничения на тип, передаваемый в качестве параметра. Например, вы можете использовать дженерики для реализации
CardDeck
и указать, что параметр типа должен наследоваться отCardGame
. - В C++ можно создать экземпляр типа, передаваемого параметром, а Java — нет.
- Java не позволяет использовать типы, передаваемые параметром (например,
Foo
вMyClass<Foo>
) для статических методов и переменных, так как они могут совместно использоваться вMyClass<Foo>
иMyClass<Bar>
. В C++ — это разные классы, поэтому тип из параметра можно использовать для статических методов и переменных. - В Java все экземпляры
MyClass<T>
, независимо от их параметров, относятся к одному и тому же типу. Параметры типов уничтожаются после компиляции. В C++ экземпляры с разными параметрами типов — различные типы.
Помните, что хотя дженерики Java и шаблоны C++ внешне похожи, это разные вещи.
Разбор задачи по книге «Карьера программиста. Как устроиться на работу в Google, Microsoft или другую ведущую IT-компанию»
24К открытий25К показов