java.lang.ClassCastException là một unchecked exception trong Java. Xảy ra khi chương trình cố chuyển đổi (cast) đối tượng của một kiểu lớp thành đối tượng của kiểu lớp khác.
Khi nào ClassCastException được ném
- Khi ép kiểu object của Parent class sang Child class type.
- Khi ép kiểu object của lớp này sang lớp kia mà không có quan hệ kế thừa giữa chúng.
Ví dụ minh họa
class ParentTest {
String parentName;
ParentTest(String n1){ parentName = n1; }
public void display() { System.out.println(parentName); }
}
class ChildTest extends ParentTest {
String childName;
ChildTest(String n2) { super(n2); childName = n2; }
public void display() { System.out.println(childName); }
}
public class Test {
public static void main(String args[]) {
ChildTest ct1 = new ChildTest("Jai");
ParentTest pt1 = new ParentTest("Adithya");
pt1 = ct1; // OK: Child → Parent (upcasting ngầm)
pt1.display();
ParentTest pt2 = new ParentTest("Sai");
ChildTest ct2 = (ChildTest)pt2; // LỖI: Parent → Child (downcasting sai)
}
}
Kết quả đầu ra
Jai
Exception in thread "main" java.lang.ClassCastException: ParentTest cannot be cast to ChildTest
at Test.main(Test.java:30)
Giải thích
pt1 = ct1: Upcasting (Child → Parent) – an toàn, ngầm định.(ChildTest)pt2: Downcasting (Parent → Child) – chỉ an toàn nếu object thực sự là Child. Ở đây pt2 là ParentTest thực sự, không phải ChildTest → ClassCastException.
Cách tránh ClassCastException
- Kiểm tra instanceof trước khi cast:
if (pt2 instanceof ChildTest) { ChildTest ct2 = (ChildTest)pt2; } - Sử dụng polymorphism đúng cách, tránh downcasting.
- Thiết kế API dùng interface/abstract class thay vì concrete class.
- Java 16+: Pattern Matching for instanceof:
if (pt2 instanceof ChildTest ct2) { ct2.display(); }
Lưu ý
- ClassCastException là unchecked – không bắt buộc try-catch/throws.
- Array cũng bị:
Object[] arr = new String[10]; arr[0] = new Integer(1); // ArrayStoreException (runtime). - Generics giúp giảm ClassCastException tại compile-time (type erasure vẫn có thể gây ra lúc runtime).