เมื่อ Override Method ที่มี throws clause ต้องปฏิบัติกฎต่อไปนี้
กฎที่ 1: Parent ไม่โยน Exception
Child ไม่สามารถโยน Checked Exception ใหม่ได้ แต่โยน Unchecked Exception ได้
class Parent {
void doSomething() { }
}
class Child extends Parent {
void doSomething() throws IllegalArgumentException { } // OK - Unchecked
// void doSomething() throws IOException { } // ERROR - Checked
}
กฎที่ 2: Parent โยน Checked Exception
Child สามารถโยนได้:
- Exception เดียวกัน
- Subclass ของ Exception นั้น (Specific มากกว่า)
- ไม่โยนเลย (ลบ throws ออกได้)
- Unchecked Exception ใดๆ
class Parent {
void doSomething() throws IOException, ParseException { }
void doSomethingElse() throws IOException { }
}
class Child extends Parent {
void doSomething() throws IOException { } // OK - Subset
void doSomethingElse() throws FileNotFoundException, EOFException { } // OK - Subclasses of IOException
}
กฎที่ 3: Parent โยน Unchecked Exception
Child โยน Unchecked Exception อะไรก็ได้ (ไม่เกี่ยวข้องก็ได้)
class Parent {
void doSomething() throws IllegalArgumentException { }
}
class Child extends Parent {
void doSomething() throws ArithmeticException, BufferOverflowException { } // OK
}
ตัวอย่างโค้ดเต็ม
import java.io.*;
class SuperClassTest {
public void test() throws IOException {
System.out.println("SuperClassTest.test() method");
}
}
class SubClassTest extends SuperClassTest {
public void test() { // ไม่โยน IOException - OK (น้อยกว่า Parent)
System.out.println("SubClassTest.test() method");
}
}
public class OverridingExceptionTest {
public static void main(String[] args) {
SuperClassTest sct = new SubClassTest();
try {
sct.test();
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
}
ผลลัพธ์
SubClassTest.test() method
สรุปกฎ (Exception Hierarchy)
| Parent Throws | Child Can Throw |
|---|---|
| Nothing | Unchecked Only |
| Checked (IOException) | Same, Subclasses, None, Any Unchecked |
| Unchecked (RuntimeException) | Any Unchecked (Even unrelated) |
เหตุผล
Liskov Substitution Principle: Subclass ต้องทำได้ทุกอย่างที่ Parent ทำได้ + อาจทำเพิ่ม แต่ ไม่ควรโยน Checked Exception ใหม่ที่ Caller ไม่คาดหวัง (Caller Catch Parent Exception แล้ว)