Java generics phần 1 – Goals | GiangTester Blog

Trước khi đi vào định nghĩa, nhắc lại 1 số kiến thức chung:

Generics nghĩa là linh động, linh hoạt, tùy vào điều kiện A để làm việc X, tùy vào điều kiện B để làm việc Y. Đại khái là không cố định.

Generics trong Java là parameterized types, có nghĩa là bạn có thể tạo ra 1 class/interface/method mà có kiểu dữ liệu (data type) linh động và có thể truyền từ ngoài vào như parameter vậy. Khi đó, class/interface/method sẽ được gọi là generics class, generics method.

Đôi khi chúng ta viết 1 class hoặc 1 biến mà mục đích là 1 dạng template để phục vụ cho nhiều type khác nhau, chúng ta có xu hướng chọn type là Object. Ví dụ:

id có thể là String, Integer hoặc bất kỳ reference type nào

Vấn đề chính là kiểu viết này là bạn phải chấp nhận việc explicit casting và như thế là bạn mất type safety.

Bạn sẽ phải cast trước rồi mới gọi method như sau:

Và rất có thể bạn sẽ gặp phải Runtime Exception: ClassCastException.

Thay vì việc sử dụng Object để làm type chung thì bạn có sử dụng Type Parameter để định nghĩa cho biến đó.

rồi bạn cho biết T là gì trước khi gọi vào các method subString hay intValue. Điều tuyệt vời là bạn sẽ không bao giờ bị ClassCastException. Nếu bạn đã xác định T là String, mà bạn lại assign Integer cho id thì sẽ bị lỗi compile luôn.

Chốt lại: Generics giúp bạn “đẩy” lỗi từ Runtime (lúc program chạy) sang lúc compile time (lúc code), tìm bug sớm hơn, lúc chạy ít lỗi hơn.

Code không có generics

List numbers = new ArrayList();
numbers.add(123);
numbers.add("abc");

for (int i = 0; i < numbers.size(); i++) {
    if ((Integer) numbers.get(i) > 10)    //cast here
        System.out.println("greater than 10");
}

/*Exception in thread "main" java.lang.ClassCastException: 
class java.lang.String cannot be cast to class java.lang.Integer 
(java.lang.String and java.lang.Integer */