Trong hướng dẫn này, chúng ta sẽ tìm hiểu về Generics trong Java, cách tạo lớp và phương thức generics và những ưu điểm của nó với sự trợ giúp của các ví dụ.

Generics trong Java cho phép chúng ta tạo một lớp, giao diện và phương thức duy nhất có thể được sử dụng với các loại dữ liệu (đối tượng) khác nhau.

Điều này giúp chúng tôi sử dụng lại mã của mình.

Lưu ý : Generics không làm việc với các kiểu dữ liệu ( int, float, char, vv).

1. Lớp Generics trong Java

Chúng ta có thể tạo một lớp có thể được sử dụng với bất kỳ loại dữ liệu nào. Một lớp như vậy được gọi là Generics Class.

Đây là cách chúng ta có thể tạo một lớp generics trong Java:

Ví dụ: Tạo một Lớp Generics

/*
Cafedev.vn - Kênh thông tin IT hàng đầu Việt Nam
@author cafedevn
Contact: cafedevn@gmail.com
Fanpage: https://www.facebook.com/cafedevn
Group: https://www.facebook.com/groups/cafedev.vn/
Instagram: https://instagram.com/cafedevn
Twitter: https://twitter.com/CafedeVn
Linkedin: https://www.linkedin.com/in/cafe-dev-407054199/
Pinterest: https://www.pinterest.com/cafedevvn/
YouTube: https://www.youtube.com/channel/UCE7zpY_SlHGEgo67pHxqIoA/
*/

class Main {
  public static void main(String[] args) {

    // initialize generic class
    // with Integer data
    GenericsClass<Integer> intObj = new GenericsClass<>(5);
    System.out.println("Generic Class returns: " + intObj.getData());

    // initialize generic class
    // with String data
    GenericsClass<String> stringObj = new GenericsClass<>("Java Programming");
    System.out.println("Generic Class returns: " + stringObj.getData());
  }
}

// create a generics class
class GenericsClass<T> {

  // variable of T type
  private T data;

  public GenericsClass(T data) {
    this.data = data;
  }

  // method that return T type variable
  public T getData() {
    return this.data;
  }
}

Đầu ra

Generic Class returns: 5
Generic Class returns: Java Programming

Trong ví dụ trên, chúng ta đã tạo một lớp Generics có tên GenericsClass. Lớp này có thể được sử dụng để làm việc với bất kỳ loại dữ liệu nào.

class GenericsClass<T> {…}

Đây, T được sử dụng bên trong dấu ngoặc nhọn <> cho biết tham số kiểu . Bên trong lớp Main, chúng tôi đã tạo hai đối tượng GenericsClass

  • intObj – Đây, tham số kiểu T được thay thế bởi Integer. Bây giờ, GenericsClass hoạt động với dữ liệu số nguyên.
  • stringObj – Đây, tham số kiểu T được thay thế bởi String. Bây giờ,GenericsClass hoạt động với dữ liệu chuỗi.

2. Phương thức Java Generics

Tương tự như lớp generics, chúng ta cũng có thể tạo một phương thức có thể được sử dụng với bất kỳ loại dữ liệu nào. Một lớp như vậy được gọi là Phương thức Generics.

Đây là cách chúng ta có thể tạo một lớp generics trong Java:

Ví dụ: Tạo một Phương thức Generics

class Main {
  public static void main(String[] args) {

    // initialize the class with Integer data
    DemoClass demo = new DemoClass();

    // generics method working with String
    demo.<String>genericsMethod("Java Programming");

    // generics method working with integer
    demo.<Integer>genericsMethod(25);
  }
}

class DemoClass {

  // creae a generics method
  public <T> void genericsMethod(T data) {
    System.out.println("Generics Method:");
    System.out.println("Data Passed: " + data);
  }
}

Đầu ra

Generics Method:
Data Passed: Java Programming
Generics Method:
Data Passed: 25

Trong ví dụ trên, chúng tôi đã tạo một phương thức chung có tên genericsMethod.

public <T> void genericMethod(T data) {…}

Ở đây, tham số kiểu <T> được chèn sau công cụ sửa đổi public và trước kiểu trả về void.

Chúng ta có thể gọi phương thức generics bằng cách đặt kiểu thực <String>và <Integer>bên trong dấu ngoặc nhọn trước tên phương thức.

demo.<String>genericMethod("Java Programming");

demo.<Integer>genericMethod(25);

Lưu ý : Chúng ta có thể gọi phương thức generics mà không bao gồm tham số kiểu. Ví dụ,

demo.genericsMethod("Java Programming");

Trong trường hợp này, trình biên dịch có thể khớp với tham số kiểu dựa trên giá trị được truyền cho phương thức.

3. Các loại generics

Nói chung, tham số kiểu có thể chấp nhận bất kỳ kiểu dữ liệu nào (ngoại trừ kiểu nguyên thủy).

Tuy nhiên, nếu chúng ta chỉ muốn sử dụng generic cho một số kiểu cụ thể (chẳng hạn như chấp nhận dữ liệu kiểu số), thì chúng ta có thể sử dụng các kiểu có giới hạn.

Trong trường hợp các loại ràng buộc, chúng tôi sử dụng từ khóa extends. Ví dụ,

<T extends A>

Điều này có nghĩa là T chỉ có thể chấp nhận dữ liệu là các kiểu con của A.

Ví dụ: Các loại giới hạn

class GenericsClass <T extends Number> {

  public void display() {
    System.out.println("This is a bounded type generics class.");
  }
}

class Main {
  public static void main(String[] args) {

    // create an object of GenericsClass
    GenericsClass<String> obj = new GenericsClass<>();
  }
}

Trong ví dụ trên, chúng ta đã tạo một lớp có tên là GenericsClass. Chú ý biểu thức, chú ý biểu thức

<T extends Number>

Đây, GenericsClass được tạo với kiểu giới hạn. Điều này có nghĩa là GenericsClass chỉ có thể hoạt động với các kiểu dữ liệu là con của Number( Integer, Doublev.v.).

Tuy nhiên, chúng tôi đã tạo một đối tượng của lớp generics với String. Trong trường hợp này, chúng ta sẽ gặp lỗi sau.

GenericsClass<String> obj = new GenericsClass<>();
                                                 ^
    reason: inference variable T has incompatible bounds
      equality constraints: String
      lower bounds: Number
  where T is a type-variable:
    T extends Number declared in class GenericsClass

4. Ưu điểm của Generics trong Java

4.1. Khả năng tái sử dụng mã

Với sự trợ giúp của generics trong Java, chúng ta có thể viết mã hoạt động với các loại dữ liệu khác nhau. Ví dụ,

public <T> void genericsMethod(T data) {...}

Ở đây, chúng tôi đã tạo ra một phương thức chung. Phương thức tương tự này có thể được sử dụng để thực hiện các hoạt động trên dữ liệu số nguyên, dữ liệu chuỗi, v.v.

4.2. Kiểm tra kiểu thời gian biên dịch

Các tham số kiểu của Generics cung cấp thông tin về các loại dữ liệu sử dụng trong mã generics. Ví dụ,

// using Generics
GenericsClass<Integer> list = new GenericsClass<>();

Ở đây, chúng tôi biết rằng GenericsClass chỉ làm việc với dữ liệu Integer.

Bây giờ, nếu chúng ta cố gắng truyền dữ liệu không phải là Integer vào lớp này, chương trình sẽ tạo ra lỗi tại thời điểm biên dịch.

4.3. Được sử dụng với collection

Khung tập hợp sử dụng khái niệm generic trong Java. Ví dụ,

// creating a string type ArrayList
ArrayList<String> list1 = new ArrayList<>();

// creating a integer type ArrayList
ArrayList<Integer> list2 = new ArrayList<>();

Trong ví dụ trên, chúng ta đã sử dụng cùng một lớp ArrayList để làm việc với các kiểu dữ liệu khác nhau.

Tương tự như ArrayList, các khoản thu khác ( LinkedList, Queue, Maps, và vân vân) cũng mang tính tổng quát trong Java.

Cài ứng dụng cafedev để dễ dàng cập nhật tin và học lập trình mọi lúc mọi nơi tại đây.

Nguồn và Tài liệu tiếng anh tham khảo:

Tài liệu từ cafedev:

Nếu bạn thấy hay và hữu ích, bạn có thể tham gia các kênh sau của cafedev để nhận được nhiều hơn nữa:

Chào thân ái và quyết thắng!

Đăng ký kênh youtube để ủng hộ Cafedev nha các bạn, Thanks you!