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