ฉันสะดุดรหัสมองสิ่งนี้:
void run() {
try {
doSomething();
} catch (Exception ex) {
System.out.println("Error: " + ex);
throw ex;
}
}
void doSomething() {
throw new RuntimeException();
}
รหัสนี้ทำให้ฉันประหลาดใจเพราะมันดูเหมือนว่า - วิธีการที่run()
มีความสามารถในการโยนException
เพราะมันจับException
แล้ว rethrows แต่วิธีการที่ไม่ได้ประกาศว่าจะโยนException
และเห็นได้ชัดว่าไม่จำเป็นต้องเป็น รหัสนี้รวบรวมได้ดี (ใน Java 11 อย่างน้อย)
ความคาดหวังของฉันคือฉันจะต้องประกาศthrows Exception
ในrun()
-method
ข้อมูลเพิ่มเติม
ในทำนองเดียวกันหากdoSomething
มีการประกาศให้โยนIOException
ดังนั้นIOException
จะต้องประกาศในวิธีการrun()
เท่านั้นแม้ว่าException
จะถูกจับและโยนใหม่
void run() throws IOException {
try {
doSomething();
} catch (Exception ex) {
System.out.println("Error: " + ex);
throw ex;
}
}
void doSomething() throws IOException {
// ... whatever code you may want ...
}
คำถาม
Java มักชอบความชัดเจนเหตุผลของพฤติกรรมนี้คืออะไร มันเป็นอย่างนี้เสมอไหม? อะไรใน Java Language Specification อนุญาตให้run()
วิธีการที่ไม่จำเป็นต้องประกาศthrows Exception
ในตัวอย่างโค้ดข้างต้น? (ถ้าฉันจะเพิ่มเข้าไป IntelliJ เตือนฉันว่าException
ไม่เคยถูกโยนทิ้ง)
-source 1.6
ค่าสถานะทำให้เกิดข้อผิดพลาดการคอมไพล์ตามที่คาดไว้ การคอมไพล์ด้วยความเข้ากันได้ของแหล่งที่มา 7 ไม่ทำให้เกิดข้อผิดพลาดในการรวบรวม
In detail, in Java SE 7 and later, when you declare one or more exception types in a catch clause, and rethrow the exception handled by this catch block, the compiler verifies that the type of the rethrown exception meets the following conditions : 1. 1. The try block is able to throw it. 2. There are no other preceding catch blocks that can handle it. 3. It is a subtype or supertype of one of the catch clause's exception parameters.
javac
- ฉันเคยเจอกับกรณีที่คอมไพเลอร์ Eclipse นั้นอ่อนโยนกว่า