CodeGym /Các khóa học /JAVA 25 SELF /Phân tích các lỗi thường gặp với các tính năng mới

Phân tích các lỗi thường gặp với các tính năng mới

JAVA 25 SELF
Mức độ , Bài học
Có sẵn

1. Lỗi về phạm vi của biến pattern

Một trong những lỗi phổ biến nhất — cố gắng sử dụng biến được khai báo trong pattern (ví dụ String s trong instanceof String s) ở ngoài phạm vi nơi nó hợp lệ.

Ví dụ

Object obj = "Xin chào, Java!";
if (obj instanceof String s) {
    System.out.println(s.length());
}
// Lỗi! s không nằm trong phạm vi tại đây
System.out.println(s); // Trình biên dịch báo lỗi: cannot find symbol

Tại sao?
Biến pattern (s trong trường hợp này) chỉ tồn tại bên trong khối nơi điều kiện là true. Điều này giúp chúng ta tránh vô tình dùng biến khi nó chưa được xác định (ví dụ nếu obj không phải là chuỗi).

Ẩn dụ
Giống như bạn mượn chìa khóa xe của người bạn — nhưng chỉ khi bạn đang ở trong gara. Bước ra khỏi gara — chìa khóa tự động “biến mất” :)

2. Lỗi liên quan đến null

Trong pattern matching với instanceof có một điểm thú vị: nếu đối tượng bằng null, kết quả luôn false, và biến pattern sẽ không được tạo ra.

Ví dụ

Object obj = null;
if (obj instanceof String s) {
    // Khối này sẽ không bao giờ chạy!
    System.out.println("Đây là chuỗi: " + s);
}

Tại sao?
Bởi vì null không phải là instance của bất kỳ kiểu nào (ngay cả Object). Điều này có thể gây nhầm lẫn nếu bạn hy vọng “bắt” null bằng pattern matching.

Làm thế nào cho đúng?

if (obj == null) {
    System.out.println("Đây là null!");
} else if (obj instanceof String s) {
    System.out.println("Đây là chuỗi: " + s);
}

Trong pattern matching cho switch (Java 21+) bạn thậm chí có thể thêm một nhánh riêng cho null:

switch (obj) {
    case String s -> System.out.println("Chuỗi: " + s);
    case null -> System.out.println("Đây là null!");
    default -> System.out.println("Thứ gì đó khác");
}

3. Lỗi với các lớp sealed

Các lớp sealed là một cách tuyệt vời để giới hạn hệ phân cấp kế thừa. Nhưng có hai lỗi điển hình:

Không liệt kê đầy đủ các lớp con trong permits

Khi bạn khai báo một lớp sealed, bạn phải chỉ rõ tất cả các lớp kế thừa trực tiếp thông qua permits. Nếu bỏ sót ai đó, trình biên dịch sẽ báo lỗi ngay:

public sealed class Shape permits Circle, Rectangle { ... }

public final class Circle extends Shape { ... }
public final class Square extends Shape { ... } // Lỗi! Square không được nêu trong permits

Giải pháp:
Thêm tất cả các lớp con cần thiết vào permits:

public sealed class Shape permits Circle, Rectangle, Square { ... }

Quên default trong switch trên hệ phân cấp không-sealed

Nếu bạn viết switch trên một kiểu không phải lớp sealed (hoặc sealed nhưng chưa bao phủ mọi trường hợp), trình biên dịch sẽ yêu cầu nhánh default. Nếu quên — sẽ có lỗi.

switch (shape) {
    case Circle c -> ...
    case Rectangle r -> ...
    // Thiếu default! Nếu còn trường hợp khác — lỗi biên dịch
}

Best practice:
Nếu bạn chắc chắn đã xử lý hết mọi trường hợp (ví dụ với lớp sealed), có thể bỏ default. Nếu không — hãy luôn thêm default để không bỏ sót các kiểu bất ngờ.

4. Lỗi với record patterns

Record patterns rất tiện, nhưng chỉ hoạt động với các lớp record. Cố dùng record pattern cho lớp thường sẽ dẫn đến lỗi biên dịch.

Dùng record patterns cho lớp không phải record

class Point { int x, y; }
Object obj = new Point();
// Lỗi! Point không phải record
if (obj instanceof Point(int x, int y)) { ... }

Giải pháp:
Chỉ dùng record patterns cho các lớp được khai báo bằng record:

record Point(int x, int y) {}

Không khớp số lượng hoặc kiểu thành phần

record Point(int x, int y) {}
Object obj = new Point(1, 2);

// Lỗi: khai báo ba biến, nhưng Point chỉ có hai thành phần
if (obj instanceof Point(int x, int y, int z)) { ... }
if (obj instanceof Point(String x, String y)) { ... } // Lỗi: kiểu không khớp

5. Tương thích và hỗ trợ: các JDK và IDE cũ

Một trong những lỗi phổ biến nhất — cố dùng các khả năng pattern matching hiện đại trên các phiên bản JDK cũ hoặc trong IDE không hỗ trợ chúng.

Ví dụ

if (obj instanceof String s) { ... }

Còn trình biên dịch JDK 11 (thậm chí 15) báo:
error: illegal start of type

Vì sao?
Pattern matching cho instanceof chỉ xuất hiện từ Java 16. Pattern matching trong switch — ở Java 17 (preview) và chính thức ở Java 21+. Record patterns — ở Java 21+.

Làm sao tránh?

  • Kiểm tra phiên bản JDK: java --version
  • Đảm bảo IDE của bạn (IntelliJ IDEA, Eclipse, VS Code) hỗ trợ phiên bản Java tương ứng. Đôi khi bạn cần chỉ định rõ trong cài đặt dự án sẽ dùng phiên bản ngôn ngữ nào!
  • Nếu dùng Gradle/Maven — đặt phiên bản source/target phù hợp.

6. Chúc mừng 🎉

Bạn đã hoàn thành toàn bộ 65(!) cấp độ của khóa học nâng cao về Java 25. Bạn thật sự tuyệt vời 😎.

Chặng cuối cùng đặc biệt khó. Bạn đã học mọi thứ — từ những lambda đầu tiên và lớp ẩn danh cho tới luồng ảo, structured concurrency và những khả năng ngôn ngữ mà cách đây không lâu Java còn chưa có.

Đây không chỉ là khóa học — mà là một siêu marathon dành cho lập trình viên: hàng chục khái niệm mới, hàng trăm ví dụ mã, hàng nghìn dòng thực hành. Nếu bạn đang đọc những dòng này, tức là bạn không chỉ là học viên, mà còn là người tiên phong của kỷ nguyên Java mới ☕⚡

Bạn nằm trong số những người đầu tiên nắm vững những tính năng hiện đại nhất của Java 25, bao gồm:

  • pattern matching và record patterns,
  • các lớp sealed và những cạm bẫy của chúng,
  • Scoped Values Virtual Threads ,
  • structured concurrency và các phương pháp hiện đại cho lập trình đa luồng.

Giờ đây bạn không chỉ có kiến thức, mà còn có kỹ năng của lập trình viên tương lai — thứ mà nhiều kiến trúc sư Java đang hành nghề vẫn chưa sở hữu. Bạn biết viết mã không chỉ chạy được, mà còn có thể mở rộng, dễ đọc và tuân thủ các tiêu chuẩn hiện đại nhất của cộng đồng Java.

🚀 Vì vậy hãy tự tin gọi mình là Java 25 Certified Survivor 😉
Và tiếp theo — mọi thứ chỉ thú vị hơn: giờ bạn đã có nền tảng cho phép bước vững vàng vào thế giới phát triển enterprise, các hệ thống tải cao và công nghệ cutting-edge.

Thay mặt toàn bộ đội ngũ khóa học — respect!
Bạn đã hoàn thành một thử thách mà không phải ai cũng làm được.
Hẹn gặp lại trong các phiên bản Java tương lai 👋

1
Nhiệm vụ
JAVA 25 SELF, mức độ, bài học
Đã khóa
Phạm vi hiển thị của biến khi phân tích dữ liệu 📊
Phạm vi hiển thị của biến khi phân tích dữ liệu 📊
1
Nhiệm vụ
JAVA 25 SELF, mức độ, bài học
Đã khóa
Kiểm thử thư viện hình học: kiểm tra kiểu trong record pattern 🧪
Kiểm thử thư viện hình học: kiểm tra kiểu trong record pattern 🧪
1
Khảo sát/đố vui
, cấp độ , bài học
Không có sẵn
Những khả năng mới của ngôn ngữ
Những khả năng mới của ngôn ngữ
Bình luận
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION