Дженерики засоби параметризовані типи . Ідея полягає в тому, щоб дозволити типу (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. Реалізація загальних алгоритмів: Використовуючи дженерики, ми можемо реалізувати алгоритми, які працюють на різних типах об’єктів, і водночас вони є типобезпечними.