[英]Why is throwing a checked exception type allowed in this case?
我偶然注意到這個throw
語句(從一些更復雜的代碼中提取)編譯:
void foo() {
try {
} catch (Throwable t) {
throw t;
}
}
對於一個短暫而快樂的時刻,我認為已經檢查過的異常最終決定已經死了,但它仍然在這方面很高興:
void foo() {
try {
} catch (Throwable t) {
Throwable t1 = t;
throw t1;
}
}
try
塊不必為空; 它似乎可以有代碼,只要該代碼不會拋出已檢查的異常。 這似乎是合理的,但我的問題是,語言規范中的哪些規則描述了這種行為? 據我所知 , §14.18town語句明確禁止它,因為t
表達式的類型是一個已檢查的異常,並且它沒有被捕獲或聲明被拋出。 (?)
這是因為Java 7中引入的Project Coin中包含的更改允許通過重新拋出原始異常來進行常規異常處理。 這是一個適用於Java 7但不適用於Java 6的示例:
public static demoRethrow() throws IOException {
try {
throw new IOException("Error");
}
catch(Exception exception) {
/*
* Do some handling and then rethrow.
*/
throw exception;
}
}
您可以在此處閱讀解釋更改的整篇文章。
我認為,在措辭§14.18的throw
聲明 ,你指的是在JLS一個錯誤-應該已經更新了Java SE 7中,而不是文字。
描述預期行為的JLS文本位於第11.2.2節語句的異常分析中 :
throw
語句表達式是catch
子句C的最終或有效最終異常參數的throw語句可以拋出異常類E iff:
- E是一個異常類,聲明C的
try
語句的try
塊可以拋出; 和- E的賦值與C的任何可捕獲異常類兼容; 和
- E與同一
try
語句中在C左側聲明的catch
子句的任何可捕獲異常類不兼容。
第一個要點是相關要點; 因為catch
-clause參數t
是有效的最后(這意味着它從未分配或增加或減少;見§4.12.4 final
變量 ), throw t
只能扔東西的try
塊可以拋出。
但正如您所說,§14.18中的編譯時檢查不會對此作出任何限制。 §11.2.2不決定允許什么,不允許什么; 相反,它應該是對可以拋出的各種限制的后果的分析。 (這種分析確實反饋到規范的更規范的部分 - §14.18本身在其第二個子彈點中使用它 - 但§14.18不能只說“如果它拋出一個它不能的例外它是編譯時錯誤拋出§11.2.2“,因為這將是循環的。)
所以我認為需要調整§14.18以適應§11.2.2的意圖。
很好找!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.