You are on page 1of 9

BÁO CÁO LÝ THUYẾT

CHỦ ĐỀ: GENERICS TRONG JAVA VÀ ỨNG DỤNG

Generic là gì? Tại sao lại cần Generic


- Trước khi đưa ra khái niệm Generic là gì, cùng xem qua một đoạn code
trước khi có Generic.
Code ví dụ :
o public class KhongCoGeneric {
o
o public static void main(String[] args) {
o
o List numbers = Arrays.asList(1,2,3,4);
o for(Object number: numbers) {
o Integer numberAsInteger = (Integer)number;
o System.out.print(numberAsInteger.intValue() + " ");
o }
o System.out.println("\nIntegers with generics..");
o }
}

- Trong ví dụ trên ta thấy để in ra được dãy số, chúng ta cần cast toàn
bộ Object trong List sang Integer, điều này khiến việc code trở nên phức
tạp. Mõi lần sử dụng các phần tử trong List chúng ra lại phải cast nó sang
đối tượng chúng a cần
- Bây giờ chúng ta hãy xem qua đoạn code có sử dụng Generic:

Code ví dụ:

o public class CoGeneric {


o
o public static void main(String[] args) {
o System.out.println("\nIntegers với generic...");
o List<Integer> integers = Arrays.asList(1,2,3,4);
o for(Integer integer: integers) {

1
o System.out.print(integer + " ");}
o }
}

o Với việc dùng Generic chúng ta có thể thấy giờ đây có thể dụng List một
cách đơn giản hơn, chúng ra không cần việc cast các phần tử trong List nữa
thay vào đó lúc khao báo chỉ cần thêm tên class chúng ra cần dùng là xong.

o Khái niệm: Generic là một lớp chung có thể tham chiếu đến bất cứ lớp nào.
Nó là một đại diện, biểu trưng cho các lớp trong method, class, interface,...

1. Menthod Generic ( Phương thức Generic)


- Nghĩ thế nào nếu chúng ta tạo ra một phương mà có thể sử dụng trên tất cả
các class? Sẽ thật tiện dụng đúng không? Và đây cũng là một tác dụng của
việc sử dụng Generic! Bây giờ chúng ta cùng xây dựng một Phương thức
Generic:
- Lấy 2 đối tượng là Car và Dog:
o Car

o public class Car {


o
o private String name;
o private int speed; // kilometer per hour
o
o public Car() {
o
o }
o
o public Car(String name, int speed) {
o this.name = name;
o this.speed = speed;
o }
o
o @Override
o public String toString() {
o return "Ten xe: " + name + " Toc do: " + speed;
o }
}

o Dog

2
o package main.java.com.group3.genericjava;
o
o public class Dog {
o
o private String name;
o private int cost;
o
o public Dog() {
o }
o
o public Dog(String name, int cost) {
o this.name = name;
o this.cost = cost;
o }
o
o @Override
o public String toString() {
o return "Ten cho: " + name + " Gia: " + cost;
o }
}

- Như chúng ta thấy 2 class trên hoàn toàn khác biệt nhau và không hề có mối
liên hệ với nhau. Bây giờ chúng ta sẽ tạo ra một phương thức in ra thông tin
của các đối tượng Car và Dog.

Code ví dụ:
o public class MethodGeneric {
o
o public static <T> void inThongTin(T anything) {
o System.out.println("Thong tin: \n" + anything.toString());
o }
o
o public static void main(String[] args) {
o Dog dog = new Dog("Pug", 1000);
o Car car = new Car("Honda Civic", 10000);
o
o inThongTin(dog);
o inThongTin(car);
o }
}
3
Kết quả:

- Như vậy chúng ta có thể thấy nhờ dùng Generic chúng ta có thể tạo ra một
Method Generic, một phương thưc chúng ta có thể sử dụng cho tất cả các
đối tượng.
2. Class Generic
- Tương tự ở các phương thức ở class chúng ta vẫn có thể dùng Generic

Với 1 Generic:
o public class KetQua<T> {
o
o private T result;
o
o public KetQua() {
o
o }
o
o public T getResult() {
o return result;
o }
o
o public void setResult(T t) {
o this.result = t;
o }
}
Với nhiều Generic:
o public class Couple<K, V> { // co the them nhieu generic khác: vd
Coupe<K, VF, V>
o
o private K key;
o private V value;
4
o
o public Couple(K key, V value) {
o this.key = key;
o this.value = value;
o }
o
o public K getKey() {
o return key;
o }
o
o public void setKey(K key) {
o this.key = key;
o }
o
o public V getValue() {
o return value;
o }
o
o public void setValue(V value) {
o this.value = value;
o }
}
Một số ví dụ về Generic trong class:
o public class GenericClassVidu {
o
o public static void main(String[] args) {
o Couple<String, Integer> couple = new Couple<>("Nguyen Van
A", 50);
o
o System.out.println("Key: " + couple.getKey());
o System.out.println("Value: " + couple.getValue());
o }
}
Kết quả:

5
- Như vậy thông qua sử dụng Generic chúng ta đã tạo ra một class có thể sử
dụng với nhiều class kacs nhau.
3. Extends trong Generic
- Genera bản chất nó là một đại diện của class nên chúng ra cũng có thể thực
hiện việc extends trên nó. Cùng xem qua ví dụ về việc extends trên Generic:

o public class GenericVoiExtends {


o
o public static <T extends Car> void inThongTin(T anything) {
o System.out.println("Thong tin: \n" + anything.toString());
o }
o
o public static void main(String[] args) {
o Dog dog = new Dog("Pug", 1000);
o Car car = new Car("Honda Civic", 10000);
o
o inThongTin(dog); // --> Sai
o inThongTin(car);
o }
o }
- Đoạn code trên khi chạy sẽ gặp lỗi biên dịch, bởi vì phương thức chúng ra
gọi là inThongTin(T anything) với T được chỉ định phải là lớp con của
Car <T extends Car> cho nên khi chúng ra truyền biến dog thuộc
lớp Dog vào thì chương trình sẽ gặp lỗi biên dịch.
4. Kí tự ? trong Generic
- Trong Generic chúng ta có một kí tự đặc biệt đó là "?". Kí tự được gọi là
đại diện, nó đại diện cho một loại không rõ ràng.

o Rõ ràng:
o List<Car> list;
o Pair<String, Integer> pair;
Couple<Car, Owner> couple;
o Không rõ ràng:
o List<?> list;
o Pair<String, ?> pair;
Couple<?, ? extends Integer>
- Lưu ý: “?” đóng vai trò là một quy ước, một biểu trưng, một đại diện chứ
không phải là một loại cụ thể. Nó chỉ là gợi ý các quy tắc thực thi bởi

6
Generics Java rằng những loại có giá trị trong bất kỳ tình huống cụ thể mà
các ký hiệu đại diện đã được sử dụng
Code ví dụ:

 List<?> list1 = new List<Car> // --> Dung


 List<? extend Dog> list2 = new List<Car> // --> Sai
5. Lưu ý khi sử dụng
- Không thể gọi Generics bằng kiểu dữ liệu nguyên thuỷ

o Có lớp Pair: Pair<K,V>


o Chúng ta không thể dùng: Pair<int, char>
o Mà phải thế này: Pair<Integer, Character>

- Không thể tạo instances của kiểu dữ liệu Generics


o Generic là một đại diện, là một biểu trưng, vậy chứ ta có thể khỏi tạo
nó không? Đáp án là không. Chúng ta không thể khởi tạo
một Generic như một class bình thường được.
 Ví dụ:
 public class KetQua<T> {

 private T result;

 public KetQua() {
 result = new T() // -->
 }

 public T getResult() {
 return result;
 }

 public void setResult(T t) {
 this.result = t;
 }
}
o Vậy nếu muốn khởi tạo chúng ta phải làm thế nào? Chủng ta cần cung
cấp cho Java đối tượng Class.
 Ví dụ:
 public class KetQua<T> {

7
 private T result;

 public KetQua(Class<T> tClass) {
 T res = tClass.newInstance(); // --> Dung
 }

 public T getResult() {
 return result;
 }

 public void setResult(T t) {
 this.result = t;
 }
}

- Không thể sử dụng static cho Generics


o public class MobileDevice<T> {
o private static T os;
o }
- Không thể ép kiểu hoặc sử dụng instanceof
o public static <E> void rtti(List<E> list) {
o if (list instanceof ArrayList<Integer>) { // --> Sai
o // ...
o }
o }
o
o List<Integer> li = new ArrayList<>();
o List<Number> ln = (List<Number>) li; // --> Sai
- Không thể tạo mảng với parameterized types
o class MathException<T> extends Exception { /* ... */ } // --> Sai
o class QueueFullException<T> extends Throwable { /* ... */ // --> Sai
- Không thể overload các hàm trong một lớp giống như:
o public class Example {
o public void print(Set<String> strSet) { }
o public void print(Set<Integer> intSet) { }
}
6. Tính năng quan trọng của Generic
- Kiểu đối tượng an toàn:

8
o Chúng ta chỉ có thể lưu một kiểu đối tượng duy nhất trong generics.
Nó không cho phép lưu trữ 2 đối tượng có kiểu khác nhau.
o Ví dụ:
o List<String> list = new ArrayList<>();
o list.add("Hello");
list.add(new Dog("Pug", 1000)); // --> Sai
o Lỗi ở bên trên khi dịch sẽ được phát hiện ra lỗi không dẫn đến lôi lỗi
lúc chương trình đã chạy (điều này rất nguy hiểm)

- Không cần phải ép kiểu:

o Trước Generics chúng ta cần phải ép kiểu, ví dụ:


o List list = new ArrayList();
o list.add("hello");
String s = (String) list.get(0);// ép kiểu
o Sau Generics chúng ta không cần phải ép kiểu đối tượng, ví dụ:
o List<String> list = new ArrayList<String>();
o list.add("hello");
String s = list.get(0);
7. Nguồn tham khảo

Bạn đã thực sự hiểu về Generics trong Java? https://techblog.vn/ban-da-


thuc-su-hieu-ve-generics-trong-java

Java:Generics https://medium.com/@cinish/java-generics-38edb8bb6b71
[Java] Generic https://medium.com/@bill_lin/java-generic-18a9f0bec22

Hướng dẫn sử dụng Java Generics -


O7planning https://o7planning.org/vi/10403/huong-dan-java-generic

Generics trong Java - VietTuts https://viettuts.vn/java-new-


features/generics-trong-java

You might also like