Узагальнення (Generic)
Generic - це параметризовані типи, за допомогою яких можна оголошувати класи, методи та інтерфейси, де тип даних заданий у вигляді параметру. Узагальнене програмування - це такий підхід до опису даних і алгоритмів, який дозволяє їх використовувати з різними типами даних без зміни їх опису.Три переваги Generic:
1. Безпека (можна провести тільки один тип об'єктів, це не дозволяє зберігати інші об'єкти).2. Не потрібно робити приведення типів.
3. Перевірка часу компіляції: помилка компіляції «краще» помилки часу виконання.
Приклад з Generic.
class Gen<T> { T ob; // оголошення об'єкта типу T
// Передати конструктору посилання на об'єкт типу T
Gen(T o) {
ob = o;
}
// Повернути ob
T getob() {
return ob;
}
// Показати тип T
void showType() {
System.out.println("Тип T: " + ob.getClass().getName());
}
}
// Код для кнопки
Gen<Integer> iOb; // Створюємо Gen-ссилку для Integer
Gen<Integer> iOb = new Gen<Integer>(77); // Створюємо об'єкт
iOb.showType(); // Показати тип даних, який використовує iOb
int value = iOb.getob(); // Отримати значення iOb
System.out.println("Значення " + value);
// Створення об'єкту Gen для String
Gen<String> strOb = new Gen<String>("Загальний текст");
strOb.showType(); // Показати тип даних, який використовує strOb
String str = strOb.getob(); // Отримати значення strOb
System.out.println("Значення: " + str);
Output:
Типом T є java.lang.Integer
Значення: 77
Типом T є java.lang.String
Значення: Узагальнений текст
В попередньому прикладі оголошено клас в такій формі:
class Gen<T> {
}
У кутових дужках використовується T - ім'я параметра типу. Це ім'я використовується як заповнювач, куди буде підставлена ім'я реального типу, переданого класу Gen при створенні реальних типів. Тобто параметр типу T застосовується в класі щоразу, коли потрібно параметр типу. Кутові дужки вказують, що параметр може бути узагальнений. Сам клас при цьому називається узагальненим класом або параметризованим типом. Далі тип T використовується для декларування об'єкта на ім'я ob:
T ob; // оголошено об'єкт типу T
Замість T буде підставлено реальний тип, який буде вказано при створенні об'єкта класу Gen. Об'єкт ob буде об'єктом типу, переданого в параметрі типу T. Якщо в параметрі T передати тип String, то екземпляр ob матиме тип String.
Розглянемо конструктор Gen ().
Get(T o) {
ob = o;
}
Параметр o має тип T. Це означає, що реальний тип параметра o визначається типом, переданим параметром типу T при створенні об'єкта класу Gen.
Параметр типу T також може бути використаний для вказівки типу значення, що повертається методу:
T getob() {
return ob;
}
Як використовувати узагальнений клас.
Можна створити версію класу Gen для цілих чисел:
Gen<Integer> iOb;
У кутових дужках вказано тип Integer, тобто це аргумент типу, який передається в параметрі типу T класу Gen. Фактично ми створюємо версію класу Gen, в якій всі посилання на тип T стають посиланнями на тип Integer.
Коли ми присвоюємо посилання на екземпляр, то кутові дужки також потрібно вказувати.
iOb = new Gen<Integer>(77);
Можна створити версію класу Gen для цілих чисел:
Gen<Integer> iOb;
Повна версія запису може бути такою:
iOb = new Gen<Integer>(new Integer(88));
Але такий запис надлишковий, так як можна використовувати автоматичну упаковку значення 77 в потрібний формат.
Аналогічно, можна було б використовувати варіант без автоупаковки для отримання значення:
int value = iOb.getob().intValue(); // зайвий код
Узагальнення працюють тільки з об'єктами. Тому не можна використовувати в якості параметра елементарні типи на кшталт int або char:
Gen<int> intOb = new Gen<int>(44); // так не можна!
Хоча об'єкти iOb і strOb мають тип Gen <T> , вони є посиланнями на різні типи і їх порівнювати не можна.
iOB = strOb; // не можна!
Використання узагальнень автоматично гарантує безпеку типів у всіх операціях, де вони задіяні. Це дуже потужний механізм, який широко використовується в Java.
Узагальнений клас з двома параметрами
Можна вказати два і більше параметрів типу через кому.
class TwoGen<T, V> {
T ob1; V ob2; // Передати конструктору ссилки на об'єкти двох типів
TwoGen(T o1, V o2) {
ob1 = o1;
ob2 = o2;
}
void showTypes() {
System.out.println("Тип T: " + ob1.getClass().getName());
System.out.println("Тип V: " + ob2.getClass().getName());
}
T getob1() {
return ob1;
}
V getob2() {
return ob2;
}
// Використання створеного класу
TwoGen<Integer, String> twogenObj = new TwoGen<Integer, String>(77, "Загальний текст");
// дізнатися типи
twogenObj.showTypes();
// дізнатися значення
int value = twogenObj.getob1();
System.out.println("Значення: " + value);
String str = twogenObj.getob2();
System.out.println("Значення: " + str);
}
Синтаксис Generic:ClassOrInterface <Type>
Приклад використання Generic в Java:
ArrayList<String>
Приклад коду:
import java.util.*;class TestGenerics1{
public static void main(String args[]){
ArrayList<String> list=new ArrayList<String>();
list.add("rahul");
list.add("jai");
//list.add(32);
//compile time error
String s=list.get(1);//не потрібно приводити типи
System.out.println("element is: "+s);
Iterator<String> itr=list.iterator();
while(itr.hasNext()){
System.out.println(itr.next());
}
}
}
Output:
element is: jai
rahul
jai
Приклад використання Generic для Map:
import java.util.*;
class TestGenerics2{
public static void main(String args[]){
Map<Integer,String> map=new HashMap<Integer,String>();
map.put(1,"vijay");
map.put(4,"umesh");
map.put(2,"ankit");
//Now use Map.Entry for Set and Iterator
Set<Map.Entry<Integer,String>> set=map.entrySet();
Iterator<Map.Entry<Integer,String>> itr=set.iterator();
while(itr.hasNext()){
Map.Entry e=itr.next();
//no need to typecast
System.out.println(e.getKey()+" "+e.getValue());
System.out.println(e.getKey()+" "+e.getValue());
}
}
}
Output:
1 vijay
2 ankit
4 umesh
T obj;
void add(T obj){
this.obj=obj;
}
T get(){
return obj;
}
}
Output:
1 vijay
2 ankit
4 umesh
Generic class
Тут використано параметр типу Т, щоб створити загальний клас конкретного типу.Приклад 1 створення generic class:
class MyGen<T>{T obj;
void add(T obj){
this.obj=obj;
}
T get(){
return obj;
}
}
Тип T може бути будь-яким (наприклад, String, Integer, Employee і т.д.).
Тип T може бути будь-яким (наприклад, String, Integer, Employee і т.д.).
Приклад 2.
class TestGenerics3{
public static void main(String args[]){
MyGen<Integer> m=new MyGen<Integer>();
m.add(2);
//m.add("vivek");
//Compile time error
System.out.println(m.get());
System.out.println(m.get());
}
}
Output:2
Output:2
Найпоширеніші типи параметрів (Parameters):
T - Type
E - Element
K - Key
N - Number
V - Value
K - Key
N - Number
V - Value