Поясніть різницю між шаблонами в C++ і дженеріками в Java


Дізнайтесь більше про нові кар'єрні можливості в EchoUA. Цікаві проекти, ринкова оплата, гарний колектив. Надсилайте резюме та приєднуйтеся до нас.

Багато програмістів вважають, що шаблони C++ і дженеріки (наприклад в Java) – це те саме, адже їх синтаксис схожий: в обох випадках можна написати щось подібне до List. Щоб знайти відмінності, давайте розберемося, що таке шаблони і дженеріки, і як вони реалізується в кожній з мов.

Дженеріки Java пов’язані з ідеєю “стирання типів” (type erasure). Ця техніка усуває параметри типів, коли вихідний код перетвориться у байткод JVM.

Припустимо, що Ви маєте Java-код:

Vector vector = new Vector ();vector.add (new String ("hello"));String str = vector.get (0);

Під час компіляції він буде перетворений:

Vector vector = new Vector ();vector.add (new String ("hello"));
String str =  (String) vector.get (0);

Використання узагальнень Java не вплинуло на наші можливості, але зробило код красивішим. Тому дженеріки в Java часто називають “синтаксичним цукром”.

Дженеріки істотно відрізняються від шаблонів C++. Шаблони в C++ є набором макросів, що створюють нову копію шаблонного коду для кожного типу. Особливо це помітно на наступному прикладі: екземпляр MyClass не зможе спільно з MyClass використати статичну змінну. Водночас два екземпляри MyClass спільно використовуватимуть статичну змінну.

Щоб проілюструвати цей приклад, розглянемо наступний код:

/*** MyClass.h ***/templateclass MyClass {public: static int val; MyClass (int v){ val = v; }};/*** MyClass.cpp ***/template
int MyClass::val;template class MyClass;template class MyClass;/*** main.cpp ***/MyClass * foo1 = new MyClass (10);MyClass * foo2 = new MyClass (15);MyClass * bar1 = new MyClass (20);MyClass * bar2 = new MyClass (35);int f1 = foo1 ->val; //буде рівне 15int f2 = foo2 ->val; //буде рівне 15int b1 = bar1 ->val; //буде рівне 35int b2 = bar2 ->val; //дорівнюватиме 35

У Java різні екземпляри MyClass можуть спільно використати статичні змінні, незалежно від параметрів типу.

Через відмінності в архітектурі дженеріки Java і шаблони C++ значно різняться:

  • Шаблони C++ можуть використати примітивні типи, наприклад, int, а дженеріки Java – ні, вони зобов’язані використати Integer.
  • Java дозволяє вказувати обмеження на тип, що передається як параметр. Наприклад, Ви можете використати дженеріки для реалізації CardDeck і вказати, що параметр типу повинен наслідуватись від CardGame.
  • У C++ можна створити екземпляр типу, що передається параметром, а Java – ні.
  • Java не дозволяє використати типи, що передаються параметром (наприклад, Foo у MyClass) для статичних методів і змінних, оскільки вони можуть спільно використовуватися в MyClass і MyClass. У C++ – це різні класи, тому тип з параметра можна використати для статичних методів і змінних.
  • У Java всі екземпляри MyClass, незалежно від їх параметрів, відносяться до одного типу. Параметри типів знищуються після компіляції. У C++ екземпляри з різними параметрами типів – різні типи.

Пам’ятайте, що хоча дженеріки Java і шаблони C++ зовні схожі, вони все ж різняться.

Розбір завдання за книгою “Кар’єра програміста. Як влаштуватися на роботу в Google, Microsoft або іншу провідну IT-компанію?”

Київ, Харків, Одеса, Дніпро, Запоріжжя, Кривий Ріг, Вінниця, Херсон, Черкаси, Житомир, Хмельницький, Чернівці, Рівне, Івано-Франківськ, Кременчук, Тернопіль, Луцьк, Ужгород, Кам'янець-Подільський, Стрий - за статистикою саме з цих міст програмісти найбільше переїжджають працювати до Львова. А Ви розглядаєте relocate?


Залишити відповідь

Ваша e-mail адреса не оприлюднюватиметься. Обов’язкові поля позначені *