logo

Дженерики в Java

Дженерики засоби параметризовані типи . Ідея полягає в тому, щоб дозволити типу (Integer, String, … тощо, а також типи, визначені користувачем) бути параметром для методів, класів та інтерфейсів. Використовуючи Generics, можна створювати класи, які працюють з різними типами даних. Така сутність, як клас, інтерфейс або метод, яка працює з параметризованим типом, є загальною сутністю.

Чому дженерики?

The Об'єкт є суперкласом усіх інших класів, а посилання на об’єкт може посилатися на будь-який об’єкт. Ці функції не мають безпеки типу. Дженерики додають такий тип функції безпеки. Ми обговоримо цей тип функції безпеки в наступних прикладах.



Універсали в Java схожі на шаблони в C++. Наприклад, такі класи, як HashSet, ArrayList, HashMap тощо, дуже добре використовують універсали. Існують деякі принципові відмінності між двома підходами до загальних типів.

Типи Java Generics

Загальний метод: Загальний метод Java приймає параметр і повертає деяке значення після виконання завдання. Це точно так само, як звичайна функція, однак загальний метод має параметри типу, які цитуються фактичним типом. Це дозволяє використовувати загальний метод у більш загальному вигляді. Компілятор піклується про тип безпеки, який дозволяє програмістам легко кодувати, оскільки їм не потрібно виконувати довгі індивідуальні приведення типів.

Загальні класи: Загальний клас реалізується так само, як і незагальний клас. Єдина відмінність полягає в тому, що він містить розділ параметрів типу. Може бути кілька типів параметрів, розділених комою. Класи, які приймають один або декілька параметрів, відомі як параметризовані класи або параметризовані типи.



Загальний клас

Як і C++, ми використовуємо для визначення типів параметрів у створенні загального класу. Для створення об’єктів загального класу ми використовуємо наступний синтаксис.

// To create an instance of generic class BaseType obj = new BaseType ()>

Примітка: У типі параметрів ми не можемо використовувати такі примітиви, як «int», «char» або «double».

Java






// Java program to show working of user defined> // Generic classes> // We use to specify Parameter type> class> Test {> >// An object of type T is declared> >T obj;> >Test(T obj) {>this>.obj = obj; }>// constructor> >public> T getObject() {>return> this>.obj; }> }> // Driver class to test above> class> Main {> >public> static> void> main(String[] args)> >{> >// instance of Integer type> >Test iObj =>new> Test(>15>);> >System.out.println(iObj.getObject());> >// instance of String type> >Test sObj> >=>new> Test(>'GeeksForGeeks'>);> >System.out.println(sObj.getObject());> >}> }>

>

>

Вихід

15 GeeksForGeeks>

Ми також можемо передати кілька параметрів типу в загальних класах.

Java

як відкрити файл за допомогою java




// Java program to show multiple> // type parameters in Java Generics> // We use to specify Parameter type> class> Test> {> >T obj1;>// An object of type T> >U obj2;>// An object of type U> >// constructor> >Test(T obj1, U obj2)> >{> >this>.obj1 = obj1;> >this>.obj2 = obj2;> >}> >// To print objects of T and U> >public> void> print()> >{> >System.out.println(obj1);> >System.out.println(obj2);> >}> }> // Driver class to test above> class> Main> {> >public> static> void> main (String[] args)> >{> >Test obj => >new> Test(>'GfG'>,>15>);> >obj.print();> >}> }>

>

>

Вихід

GfG 15>

Загальні функції:

Ми також можемо написати загальні функції, які можна викликати з різними типами аргументів залежно від типу аргументів, переданих у загальний метод. Компілятор обробляє кожен метод.

Java




// Java program to show working of user defined> // Generic functions> class> Test {> >// A Generic method example> >static> >void> genericDisplay(T element)> >{> >System.out.println(element.getClass().getName()> >+>' = '> + element);> >}> >// Driver method> >public> static> void> main(String[] args)> >{> >// Calling generic method with Integer argument> >genericDisplay(>11>);> >// Calling generic method with String argument> >genericDisplay(>'GeeksForGeeks'>);> >// Calling generic method with double argument> >genericDisplay(>1.0>);> >}> }>

>

які розміри екрана мого комп’ютера

>

Вихід

java.lang.Integer = 11 java.lang.String = GeeksForGeeks java.lang.Double = 1.0>

Генерики працюють лише з еталонними типами:

Коли ми оголошуємо екземпляр загального типу, аргумент типу, який передається в параметр типу, має бути посилальним типом. Ми не можемо використовувати примітивні типи даних, такі як внутр , char.

Test obj = new Test(20);>

Наведений вище рядок призводить до помилки під час компіляції, яку можна вирішити за допомогою обгорток типу для інкапсуляції примітивного типу.

Але масиви примітивних типів можна передати в параметр типу, оскільки масиви є довідковими типами.

ArrayList a = new ArrayList();>

Загальні типи відрізняються залежно від аргументів типу:

Розглянемо наступний код Java.

Java




// Java program to show working> // of user-defined Generic classes> // We use to specify Parameter type> class> Test {> >// An object of type T is declared> >T obj;> >Test(T obj) {>this>.obj = obj; }>// constructor> >public> T getObject() {>return> this>.obj; }> }> // Driver class to test above> class> Main {> >public> static> void> main(String[] args)> >{> >// instance of Integer type> >Test iObj =>new> Test(>15>);> >System.out.println(iObj.getObject());> >// instance of String type> >Test sObj> >=>new> Test(>'GeeksForGeeks'>);> >System.out.println(sObj.getObject());> >iObj = sObj;>// This results an error> >}> }>

>

>

Вихід:

error: incompatible types: Test cannot be converted to Test>

Незважаючи на те, що iObj і sObj належать до типу Test, вони є посиланнями на різні типи, оскільки їхні параметри типу відрізняються. Завдяки цьому дженерики додають безпеку типу та запобігають помилкам.

Параметри типу в Java Generics

Правила іменування параметрів типу важливі для ретельного вивчення дженериків. Загальні параметри типу:

цикли java
  • T – Тип
  • E – Елемент
  • K – ключ
  • N – число
  • V – Значення

Переваги дженериків:

Програми, які використовують Generics, мають багато переваг перед незагальним кодом.

1. Повторне використання коду: Ми можемо написати метод/клас/інтерфейс один раз і використовувати його для будь-якого типу.

2. Безпека типу: Універсальні коди роблять помилки під час компіляції, ніж під час виконання (завжди краще знати про проблеми у вашому коді під час компіляції, а не створювати помилки коду під час виконання). Припустімо, ви хочете створити ArrayList, який зберігає імена студентів, і якщо програміст помилково додає цілочисельний об’єкт замість рядка, компілятор дозволяє це. Але коли ми отримуємо ці дані з ArrayList, це спричиняє проблеми під час виконання.

Java




// Java program to demonstrate that NOT using> // generics can cause run time exceptions> import> java.util.*;> class> Test> {> >public> static> void> main(String[] args)> >{> >// Creatinga an ArrayList without any type specified> >ArrayList al =>new> ArrayList();> >al.add(>'Sachin'>);> >al.add(>'Rahul'>);> >al.add(>10>);>// Compiler allows this> >String s1 = (String)al.get(>0>);> >String s2 = (String)al.get(>1>);> >// Causes Runtime Exception> >String s3 = (String)al.get(>2>);> >}> }>

алфавіт з цифрами

>

>

Вихід:

Exception in thread 'main' java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String at Test.main(Test.java:19)>

Як дженерики вирішують цю проблему?

Визначаючи ArrayList, ми можемо вказати, що цей список може приймати лише об’єкти String.

Java




// Using Java Generics converts run time exceptions into> // compile time exception.> import> java.util.*;> class> Test> {> >public> static> void> main(String[] args)> >{> >// Creating a an ArrayList with String specified> >ArrayList al =>new> ArrayList ();> >al.add(>'Sachin'>);> >al.add(>'Rahul'>);> >// Now Compiler doesn't allow this> >al.add(>10>);> >String s1 = (String)al.get(>0>);> >String s2 = (String)al.get(>1>);> >String s3 = (String)al.get(>2>);> >}> }>

>

>

Вихід:

15: error: no suitable method found for add(int) al.add(10); ^>

3. Індивідуальне лиття типу не потрібно: Якщо ми не використовуємо універсали, тоді, у наведеному вище прикладі, кожного разу, коли ми отримуємо дані з ArrayList, ми маємо їх типізувати. Приведення типів під час кожної операції пошуку — це великий головний біль. Якщо ми вже знаємо, що наш список містить лише рядкові дані, нам не потрібно приводити його кожного разу.

Java




// We don't need to typecast individual members of ArrayList> import> java.util.*;> class> Test {> >public> static> void> main(String[] args)> >{> >// Creating a an ArrayList with String specified> >ArrayList al =>new> ArrayList();> >al.add(>'Sachin'>);> >al.add(>'Rahul'>);> >// Typecasting is not needed> >String s1 = al.get(>0>);> >String s2 = al.get(>1>);> >}> }>

>

>

4. Generics сприяє повторному використанню коду: За допомогою генериків у Java ми можемо написати код, який працюватиме з різними типами даних. Наприклад,

Скажімо, ми хочемо відсортувати елементи масиву різних типів даних, наприклад int, char, String тощо.

В основному нам знадобляться різні функції для різних типів даних.

Для простоти ми будемо використовувати бульбашкове сортування.

Але за допомогою дженерики, ми можемо досягти функції повторного використання коду.

Java




public> class> GFG {> >public> static> void> main(String[] args)> >{> >Integer[] a = {>100>,>22>,>58>,>41>,>6>,>50> };> >Character[] c = {>'v'>,>'g'>,>'a'>,>'c'>,>'x'>,>'d'>,>'t'> };> >String[] s = {>'Virat'>,>'Rohit'>,>'Abhinay'>,>'Chandu'>,>'Sam'>,>'Bharat'>,>'Kalam'> };> >System.out.print(>'Sorted Integer array : '>);> >sort_generics(a);> >System.out.print(>'Sorted Character array : '>);> >sort_generics(c);> >System.out.print(>'Sorted String array : '>);> >sort_generics(s);> > >}> >public> static> extends Comparable>void sort_generics(T[] a) { //Оскільки ми порівнюємо непримітивні типи даних //нам потрібно використовувати клас Comparable //Бульбашкова логіка сортування for (int i = 0; i 1; i++) { for (int j = 0; j++) { if (a[j].compareTo(a[j + 1]) { swap(j, j + 1, a); } } } // Друк елементів після сортування for (T i : a) { System.out.print(i + ', '); } System.out.println(); } public static void swap(int i, int j, T[] a) { T t = a[i]; a[i] = a[j]; a[j] = t; } }>

>

math pow java
>

Вихід

Sorted Integer array : 6, 22, 41, 50, 58, 100, Sorted Character array : a, c, d, g, t, v, x, Sorted String array : Abhinay, Bharat, Chandu, Kalam, Rohit, Sam, Virat,>

Тут ми створили загальний метод. Цей же метод можна використовувати для виконання операцій над цілочисельними даними, рядковими даними тощо.

5. Реалізація загальних алгоритмів: Використовуючи дженерики, ми можемо реалізувати алгоритми, які працюють на різних типах об’єктів, і водночас вони є типобезпечними.