Tận Dụng Các Tính Năng Mới Của Java 16: So Sánh Mẫu, Lớp Ghi và Lớp Đóng

Java 16 mang đến ba cải tiến trọng yếu nhằm tối ưu hóa cách xử lý dữ liệu và kiểm soát cấu trúc kế thừa: so sánh mẫu (pattern matching) được chuẩn hóa cho instanceof, lớp ghi (record) để biểu diễn dữ liệu bất biến, và lớp đóng (sealed class) để giới hạn rõ ràng các lớp con hợp lệ. Những tính năng này không chỉ giảm thiểu mã lặp mà còn nâng cao độ an toàn về kiểu và khả năng bảo trì.

So sánh mẫu với instanceof: Loại bỏ chuyển đổi tường minh

Từ Java 16, biểu thức instanceof hỗ trợ khai báo biến mẫu ngay trong điều kiện — biến chỉ tồn tại trong khối lệnh được thực thi khi kiểm tra thành công.

Object input = "Java 16 in action";
if (input instanceof String text) {
    System.out.println("Độ dài chuỗi: " + text.length());
}
// Biến 'text' KHÔNG tồn tại ở đây — phạm vi bị giới hạn

Khác với cách viết truyền thống yêu cầu kiểm tra rồi mới ép kiểu, cú pháp mới đảm bảo rằng biến text luôn có giá trị hợp lệ và đúng kiểu, đồng thời ngăn chặn việc sử dụng sai ngoài phạm vi mong muốn.

Lớp ghi: Định nghĩa dữ liệu bất biến trong một dòng

Một record là lớp bất biến chỉ chứa dữ liệu, tự động sinh phương thức truy cập, equals(), hashCode()toString(). Không cần get/set, không cần constructor thủ công.

public record User(String name, int age, String role) {
    // Constructor ngắn (compact constructor) để kiểm tra ràng buộc
    public User {
        if (age < 0 || age > 150) {
            throw new IllegalArgumentException("Tuổi phải nằm trong khoảng 0–150");
        }
        if (name == null || name.trim().isEmpty()) {
            throw new IllegalArgumentException("Tên không được rỗng");
        }
    }

    // Phương thức tùy chỉnh
    public boolean isAdult() {
        return age >= 18;
    }
}

Sử dụng:

User alice = new User("Alice", 32, "ADMIN");
System.out.println(alice.name());     // "Alice"
System.out.println(alice.isAdult());  // true
System.out.println(alice);            // User[name=Alice, age=32, role=ADMIN]

Lưu ý: Các trường trong recordfinal, không thể mở rộng (extends bị cấm), và không hỗ trợ implements trừ khi là interface.

Lớp đóng: Kiểm soát chặt chẽ cây kế thừa

Một lớp được đánh dấu sealed chỉ cho phép một danh sách tường minh các lớp con — tất cả đều phải khai báo rõ ràng cách chúng tham gia vào hệ thống kế thừa.

public sealed interface MediaType permits Audio, Video, Image {}

final class Audio implements MediaType {
    private final int bitrate;
    public Audio(int bitrate) { this.bitrate = bitrate; }
}

non-sealed class Video implements MediaType {
    private final String codec;
    public Video(String codec) { this.codec = codec; }
}

sealed class Image implements MediaType permits PngImage, JpegImage {}

final class PngImage extends Image {}
final class JpegImage extends Image {}

Mỗi lớp con bắt buộc phải chọn một trong ba từ khóa sau:

  • final: Không cho phép kế thừa thêm.
  • sealed: Cho phép mở rộng nhưng chỉ với danh sách con được phép (qua permits).
  • non-sealed: Mở lại hoàn toàn khả năng kế thừa — bất kỳ lớp nào cũng có thể mở rộng nó.

Kết hợp với so sánh mẫu, lớp đóng giúp xây dựng các biểu thức kiểm tra đầy đủ (exhaustive). Ví dụ, khi xử lý MediaType:

public String describe(MediaType media) {
    return switch (media) {
        case Audio a -> "Âm thanh: " + a.bitrate() + " kbps";
        case Video v -> "Video: mã hóa " + v.codec();
        case Image i when i instanceof PngImage -> "Ảnh PNG";
        case Image i when i instanceof JpegImage -> "Ảnh JPEG";
    };
}

Nếu sau này thêm Text vào danh sách permits, trình biên dịch sẽ báo lỗi thiếu nhánh xử lý — đảm bảo tính toàn vẹn của logic phân nhánh.

Thẻ: java16 record sealed-class pattern-matching

Đăng vào ngày 13 tháng 6 lúc 01:36