Enum trong Java: Từ khoá 'Gia Vị' giúp code GenZ 'ngon' hơn!
Java – OOP

Enum trong Java: Từ khoá 'Gia Vị' giúp code GenZ 'ngon' hơn!

Author

Admin System

@root

Ngày xuất bản

21 Mar, 2026

Lượt xem

2 Lượt

Enums

Enum trong Java: Khi các 'Thẻ Bài' định nghĩa thế giới của bạn

Chào các chiến thần GenZ, lại là anh Creyt đây! Hôm nay chúng ta sẽ 'khui' một khái niệm nghe hơi học thuật nhưng lại cực kỳ 'bá đạo' trong Java, đó là Enum. Nghe tên thì khô khan, nhưng tin anh đi, nó sẽ là 'gia vị' giúp code của em 'ngon' hơn, ít 'bug' hơn và 'clean' hơn rất nhiều.

1. Enum là gì và để làm gì? (Giải mã GenZ Style)

Thế này nhé, em cứ tưởng tượng thế giới code của chúng ta đôi khi cần những giá trị 'bất biến', tức là nó chỉ có thể là một trong số ít các lựa chọn cố định. Ví dụ:

  • Trạng thái đơn hàng: CHỜ_XÁC_NHẬN, ĐANG_GIAO, ĐÃ_GIAO, ĐÃ_HỦY.
  • Các ngày trong tuần: THỨ_HAI, THỨ_BA, ... CHỦ_NHẬT.
  • Cấp độ người dùng: ADMIN, MODERATOR, USER, GUEST.

Trước đây, có thể em sẽ dùng int (0, 1, 2, 3...) hoặc String ("PENDING", "DELIVERED"...) để đại diện cho mấy cái này. Nhưng mà, dùng int thì dễ nhầm lẫn (số 5 là gì?); dùng String thì dễ gõ sai chính tả (chữ "PENDING" thành "PENDINGG" là toang!). Đó là lúc Enum (viết tắt của Enumeration) xuất hiện như một 'siêu anh hùng'.

Enum là một kiểu dữ liệu đặc biệt cho phép em định nghĩa một tập hợp các hằng số (constants) có tên. Nó giống như việc em tạo ra một bộ 'thẻ bài Yu-Gi-Oh' với những tên gọi rõ ràng, không thể nhầm lẫn và chỉ có bấy nhiêu lá bài thôi. Không ai có thể tự tiện tạo ra một lá bài mới ngoài bộ đó cả. Nhờ vậy:

  • An toàn kiểu dữ liệu (Type Safety): Code của em chỉ chấp nhận những giá trị đã được định nghĩa. Không có chuyện nhập bừa 'trạng thái 99' hay 'ngày mai kia' vào được.
  • Dễ đọc (Readability): Thay vì if (status == 1), em có if (status == TrangThaiDonHang.DANG_GIAO). Đọc phát hiểu luôn, không cần đoán mò.
  • Dễ bảo trì (Maintainability): Nếu sau này có thêm trạng thái mới, em chỉ cần thêm vào Enum là xong, không cần mò mẫm khắp nơi sửa int hay String.

2. Code Ví Dụ Minh Họa: 'Triệu hồi' Enum

Ví dụ cơ bản: Các ngày trong tuần

Bắt đầu với cái dễ nhất: các ngày trong tuần. Chúng ta có 7 ngày, cố định, không thêm không bớt.

// Bước 1: Định nghĩa Enum của bạn
public enum NgayTrongTuan {
    THU_HAI, // Đây là một hằng số Enum
    THU_BA,
    THU_TU,
    THU_NAM,
    THU_SAU,
    THU_BAY,
    CHU_NHAT
}

// Bước 2: Sử dụng Enum trong code
public class LichLamViec {
    public static void main(String[] args) {
        NgayTrongTuan homNay = NgayTrongTuan.THU_TU;

        System.out.println("Hôm nay là: " + homNay);

        // Dùng switch-case với Enum cực kỳ hiệu quả
        switch (homNay) {
            case THU_BAY:
            case CHU_NHAT:
                System.out.println("Yay! Cuối tuần rồi, đi chơi thôi!");
                break;
            case THU_SAU:
                System.out.println("Gần cuối tuần rồi, cố lên!");
                break;
            default:
                System.out.println("Lại phải đi học/làm rồi T_T");
        }

        // Vòng lặp qua tất cả các giá trị của Enum
        System.out.println("\n--- Tất cả các ngày trong tuần ---");
        for (NgayTrongTuan ngay : NgayTrongTuan.values()) {
            System.out.println(ngay);
        }
    }
}

Kết quả sẽ là:

Hôm nay là: THU_TU
Lại phải đi học/làm rồi T_T

--- Tất cả các ngày trong tuần ---
THU_HAI
THU_BA
THU_TU
THU_NAM
THU_SAU
THU_BAY
CHU_NHAT

Thấy chưa? Rõ ràng, dễ hiểu, không sợ gõ nhầm.

Ví dụ nâng cao: Enum với thuộc tính và phương thức

Đừng coi thường Enum nhé! Nó không chỉ là tập hợp các hằng số vô tri đâu. Thực chất, mỗi hằng số trong Enum là một đối tượng (object) và bản thân Enum cũng là một class đặc biệt. Điều này có nghĩa là em có thể thêm các thuộc tính (fields), constructor và phương thức (methods) cho các hằng số Enum của mình. Nghe 'khét' chưa?

Hãy tưởng tượng TrangThaiDonHang không chỉ có tên mà còn có một mô tả tiếng Việt và một phương thức để kiểm tra xem trạng thái đó có thể chuyển sang trạng thái tiếp theo được không.

public enum TrangThaiDonHang {
    CHO_XAC_NHAN("Đơn hàng đang chờ xác nhận.", true), // Constructor được gọi ở đây
    DANG_GIAO("Đơn hàng đang trên đường đến bạn.", true),
    DA_GIAO("Đơn hàng đã được giao thành công.", false),
    DA_HUY("Đơn hàng đã bị hủy.", false);

    // Thuộc tính của mỗi hằng số Enum
    private final String moTa;
    private final boolean coTheChuyenTiep;

    // Constructor riêng cho Enum
    // Lưu ý: Constructor của Enum luôn là private hoặc package-private
    private TrangThaiDonHang(String moTa, boolean coTheChuyenTiep) {
        this.moTa = moTa;
        this.coTheChuyenTiep = coTheChuyenTiep;
    }

    // Phương thức để lấy mô tả
    public String getMoTa() {
        return moTa;
    }

    // Phương thức kiểm tra khả năng chuyển tiếp trạng thái
    public boolean isCoTheChuyenTiep() {
        return coTheChuyenTiep;
    }

    // Một phương thức ví dụ để chuyển trạng thái (đơn giản hóa)
    public TrangThaiDonHang nextState() {
        return switch (this) {
            case CHO_XAC_NHAN -> DANG_GIAO;
            case DANG_GIAO -> DA_GIAO;
            case DA_GIAO, DA_HUY -> this; // Không thể chuyển tiếp từ các trạng thái này
        };
    }
}

public class QuanLyDonHang {
    public static void main(String[] args) {
        TrangThaiDonHang donHang1 = TrangThaiDonHang.CHO_XAC_NHAN;
        TrangThaiDonHang donHang2 = TrangThaiDonHang.DANG_GIAO;
        TrangThaiDonHang donHang3 = TrangThaiDonHang.DA_GIAO;

        System.out.println("\n--- Trạng thái đơn hàng ---");
        System.out.println("Đơn hàng 1: " + donHang1.getMoTa());
        System.out.println("Có thể chuyển tiếp: " + donHang1.isCoTheChuyenTiep());
        System.out.println("Trạng thái tiếp theo (nếu có): " + donHang1.nextState().getMoTa());

        System.out.println("\nĐơn hàng 2: " + donHang2.getMoTa());
        System.out.println("Có thể chuyển tiếp: " + donHang2.isCoTheChuyenTiep());
        System.out.println("Trạng thái tiếp theo (nếu có): " + donHang2.nextState().getMoTa());

        System.out.println("\nĐơn hàng 3: " + donHang3.getMoTa());
        System.out.println("Có thể chuyển tiếp: " + donHang3.isCoTheChuyenTiep());
        System.out.println("Trạng thái tiếp theo (nếu có): " + donHang3.nextState().getMoTa());

        // Tìm một Enum constant từ String
        String trangThaiString = "DANG_GIAO";
        try {
            TrangThaiDonHang timThay = TrangThaiDonHang.valueOf(trangThaiString);
            System.out.println("\nTìm thấy trạng thái từ String: " + timThay.getMoTa());
        } catch (IllegalArgumentException e) {
            System.out.println("Không tìm thấy trạng thái: " + trangThaiString);
        }
    }
}

Output:

Gợi Ý Đọc Tiếp
Implements trong Java: Hợp đồng code cho GenZ

4 Lượt xem

--- Trạng thái đơn hàng ---
Đơn hàng 1: Đơn hàng đang chờ xác nhận.
Có thể chuyển tiếp: true
Trạng thái tiếp theo (nếu có): Đơn hàng đang trên đường đến bạn.

Đơn hàng 2: Đơn hàng đang trên đường đến bạn.
Có thể chuyển tiếp: true
Trạng thái tiếp theo (nếu có): Đơn hàng đã được giao thành công.

Đơn hàng 3: Đơn hàng đã được giao thành công.
Có thể chuyển tiếp: false
Trạng thái tiếp theo (nếu có): Đơn hàng đã được giao thành công.

Tìm thấy trạng thái từ String: Đơn hàng đang trên đường đến bạn.

Giờ thì mỗi 'thẻ bài' của em không chỉ có tên mà còn có 'hiệu ứng' riêng, 'chỉ số' riêng, tha hồ mà 'build deck' cho code!

Illustration

3. Mẹo (Best Practices) của anh Creyt để 'chiến' Enum

  • Đặt tên chuẩn chỉ: Các hằng số Enum nên viết HOA_TẤT_CẢ và dùng dấu gạch dưới (_) để phân tách từ (UPPER_SNAKE_CASE). Ví dụ: TRANG_THAI_DON_HANG, LOAI_SAN_PHAM.
  • Dùng khi nào? Chỉ dùng Enum khi em có một tập hợp giá trị cố định, hữu hạn và có liên quan đến nhau. Nếu giá trị có thể thay đổi liên tục hoặc quá nhiều thì cân nhắc dùng cách khác (ví dụ: database).
  • Đừng lạm dụng: Enum là class, nhưng nó không phải là giải pháp thay thế cho mọi class hay interface. Đừng cố nhét quá nhiều logic phức tạp vào Enum nếu nó làm code khó đọc hơn.
  • valueOf()values() là bạn thân: Nhớ hai phương thức tĩnh này nhé. values() trả về một mảng chứa tất cả các hằng số Enum. valueOf(String name) sẽ trả về hằng số Enum có tên trùng với name (nhớ là phải khớp chính xác, không thì nó ném IllegalArgumentException đấy).
  • switch statement: Enumswitch là một cặp trời sinh. Dùng switch với Enum giúp code của em cực kỳ gọn gàng và dễ đọc.
  • Tránh null: Các hằng số Enum không bao giờ là null, điều này giúp giảm thiểu lỗi NullPointerException (một trong những lỗi 'khó chịu' nhất).

4. Ứng dụng thực tế: Enum 'phủ sóng' mọi nơi

Em có để ý không, Enum được dùng ở khắp mọi nơi trong các ứng dụng/website mà em dùng hàng ngày đấy:

  • Các trang thương mại điện tử (Shopee, Tiki, Lazada): Dùng Enum cho TrangThaiDonHang, LoaiThanhToan (Tiền mặt, Chuyển khoản, Thẻ tín dụng), TrangThaiGiaoHang.
  • Các mạng xã hội (Facebook, Instagram): Dùng cho LoaiBaiViet (Ảnh, Video, Text), TrangThaiQuanHe (Độc thân, Đã kết hôn), QuyenNguoiDung (Admin, Member, Viewer).
  • Các game online: TrangThaiGame (Đang chơi, Tạm dừng, Kết thúc), LoaiVatPham (Vũ khí, Giáp, Thuốc), HuongDiChuyen (Lên, Xuống, Trái, Phải).
  • Ngân hàng điện tử: LoaiGiaoDich (Chuyển tiền, Rút tiền, Thanh toán hóa đơn), TrangThaiGiaoDich (Thành công, Thất bại, Đang xử lý).

Thấy chưa, nó không phải là thứ gì xa vời đâu, nó là 'xương sống' của rất nhiều tính năng mà em đang dùng đó.

5. Thử nghiệm của anh Creyt và khi nào nên dùng?

Anh Creyt đã 'chinh chiến' với Enum từ hồi mới ra lò, và kinh nghiệm xương máu là:

NÊN DÙNG Enum khi:

  • Giá trị cố định và biết trước: Khi em có một tập hợp các giá trị không đổi và em biết tất cả chúng ngay từ đầu (ví dụ: các mùa trong năm, các hằng số toán học).
  • Cần an toàn kiểu dữ liệu: Khi em muốn đảm bảo rằng biến chỉ nhận một trong các giá trị hợp lệ đã định nghĩa, tránh lỗi do nhập sai hoặc giá trị không mong muốn.
  • Muốn code dễ đọc và bảo trì: Thay vì các 'magic numbers' (số bí ẩn) hay 'magic strings' (chuỗi bí ẩn), Enum mang lại ý nghĩa rõ ràng cho code.
  • Khi các hằng số có thêm logic riêng: Như ví dụ TrangThaiDonHang ở trên, khi mỗi hằng số cần có thuộc tính hoặc phương thức riêng để xử lý logic cụ thể.

KHÔNG NÊN DÙNG Enum khi:

  • Giá trị quá động: Nếu tập hợp các giá trị thay đổi liên tục hoặc được tạo ra từ dữ liệu bên ngoài (ví dụ: danh sách khách hàng từ database), thì Enum không phải là lựa chọn tốt. Lúc đó hãy dùng các List, Map hoặc Class bình thường.
  • Số lượng giá trị quá lớn: Nếu em có hàng trăm, hàng ngàn giá trị, việc định nghĩa chúng trong Enum sẽ làm file code rất lớn và khó quản lý. Hãy nghĩ đến database hoặc cấu hình file.

Vậy đó, Enum là một 'công cụ' cực kỳ mạnh mẽ trong Java, giúp code của em không chỉ chạy đúng mà còn 'đẹp mã', 'dễ hiểu' và 'bền vững' hơn. Cứ luyện tập và áp dụng vào các dự án của mình, em sẽ thấy nó 'thần kỳ' đến mức nào!

Chúc các GenZ code 'sung', 'thăng hoa' và sớm trở thành 'master' nhé! Peace out! Peace!

Thuộc Series: Java – OOP

Bài giảng này được tự động xuất bản ngẫu nhiên từ thư viện kiến thức. Đừng quên đón xem các Từ khoá Hướng Dẫn tiếp theo nhé!

#tech #cyberpunk #laravel
Chỉnh sửa bài viết

Bình luận (0)

Vui lòng Đăng Nhập để Bình luận

Hỗ trợ Markdown cơ bản
Nguyễn Văn A
1 ngày trước

Tính năng này đỉnh quá ad ơi, chờ mãi mới thấy một blog Tiếng Việt có UI/UX xịn như vầy!