java.lang.ClassCastException เป็น Unchecked Exception** เกิดเมื่อพยายาม Cast Object จาก Class Type หนึ่ง เป็น อีก Class Type หนึ่ง ที่ไม่เข้ากัน
เมื่อไหร่เกิด ClassCastException
- Cast Parent Object → Child Type (Downcast ผิด: Parent ไม่ใช่ Child)
- Cast ระหว่าง Class ที่ไม่เกี่ยวข้อง (No Inheritance Relationship)
ตัวอย่างโค้ด
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 (Upcast - Implicit)
pt1.display(); // "Jai" (Polymorphism)
ParentTest pt2 = new ParentTest("Sai");
ChildTest ct2 = (ChildTest) pt2; // ERROR! Parent → Child (Downcast ผิด)
}
}
ผลลัพธ์
Jai
Exception in thread "main" java.lang.ClassCastException: ParentTest cannot be cast to ChildTest
at Test.main(Test.java:30)
วิธีป้องกัน (Safe Casting)
1. instanceof Operator (Java ทุกเวอร์ชัน)
if (pt2 instanceof ChildTest) {
ChildTest ct2 = (ChildTest) pt2;
// Safe to use ct2
} else {
System.out.println("Not a ChildTest");
}
2. Pattern Matching instanceof (Java 16+)
if (pt2 instanceof ChildTest ct2) {
// ct2 ใช้ได้เลยใน Scope นี้
ct2.display();
}
3. Try-Catch (Last Resort)
try {
ChildTest ct2 = (ChildTest) pt2;
} catch (ClassCastException e) {
// Handle
}
Best Practices
- หลีกเลี่ยง Downcast ถ้าเป็นไปได้ (Polymorphism, Visitor Pattern)
- ใช้ instanceof ก่อน Cast เสมอ
- Design ด้วย Interface/Abstract Class ลดการ Cast
- Generics ช่วย Compile-time Type Safety
ClassCastException vs ClassNotFoundException
| Exception | ประเภท | สาเหตุ |
|---|---|---|
| ClassCastException | Unchecked (Runtime) | Cast Object ผิด Type |
| ClassNotFoundException | Checked (Compile-time) | Class.forName() หา Class ไม่เจอ |