[英]Throwing both main exception and sub-type, is there a proper way?
好的,所以我在SO和程序員之間有很多與異常相關的問題,但是有太多問題要問,或者我不知道要輸入什么,或者問的人不多。
因此,假設我有一個拋出FileNotFoundException
(FNFE)的方法。 然后,我有了另一個使用第一個方法的方法,但是還會拋出IOException
(IOE)。
我的處理程序可以同時捕獲這兩者,並且各自執行不同的操作,但是我的IDE(IntelliJ)發出信號,表明我“在拋出列表中已有一個更通用的異常'java.io.IOException'”。
我知道這樣做是可行的:
public File openOrCreate(String pathStr) throws FileNotFoundException,
IOException {
try {
// Method that generates the FNFE
Path path = ReposioryProposition.getPath(pathStr);
File file = path.toFile();
catch (FileNotFoundException fnfe) {
throw fnfe;
}
if (!file.exists())
file.createNewFile(); // IOE
return file;
}
但是我需要明確地做嗎? 它是否可以在沒有顯式版本的情況下工作,或更危險的是, 有時會在沒有顯式版本的情況下工作。
為了確保我們在同一頁上,這就是我最初編寫該內容的方式:
public File openOrCreate(String pathStr) throws FileNotFoundException,
IOException {
Path path = ReposioryProposition.getPath(pathStr);
File file = path.toFile();
if (!file.exists())
file.createNewFile();
return file;
}
但是我不確定會發生什么,FNFE是被扔掉還是被吞噬了? 我的意圖是分別捕獲它們,並為另一個做不同的事情。
您只需要在throws
列表中包括更一般的異常即可。 這已經指定該方法可以拋出此異常的任何子類。
特別是,無論如何,您都必須處理更通用的異常,並且該異常處理程序還將處理子類。 如果要顯式處理子類,則必須在更一般的異常之前捕獲它:
try {
...
}
catch (FileNotFoundException e) {
// handle subclass
}
catch (IOException e) {
// handle general exception (this will not be executed if the
// exception is actually a FileNotFoundException
}
如果您已經包含IOException,則最好從throws子句中忽略FileNotFoundException。
這樣做完全不會影響行為。 FileNotFoundException仍將被拋出,您可以顯式地捕獲它(以及還具有另一個更一般的IOException捕獲)。
在throws子句中具有IOException只是表明將從此方法引發IOException或其任何子類 。 FileNotFoundException包括在其中。
但是我需要明確地做嗎? 它是否可以在沒有顯式版本的情況下工作,或更危險的是,有時會在沒有顯式版本的情況下工作。
是。 您必須明確地執行此操作,因為它是已檢查的異常。
直接拋出異常:如果僅將那些檢查過的異常添加到方法簽名中,則意味着如果在方法標題中添加throws子句,例如throws IOException
,則無需捕獲方法中的任何地方。
但這有一個缺陷,如果您正在代碼中逐行訪問n個文件,並且如果引發異常,則每一行都可能引發IOException。 您必須先關閉文件 .close()
然后再將其返回給調用的方法。 因此,僅使用this throws子句不會讓您這樣做。
因此,只需捕獲異常並在catch或finally塊中執行必要的操作即可。
僅當您不需要采取任何措施並且您希望將異常彈出到被調用方法中並且被調用方法可以處理該異常時,才將throws簽名添加到該方法中。
這是Java語言規范必須說的 :
如果V的運行時類型與(§5.2)try語句的任何catch子句的可捕獲異常類的賦值兼容, 則選擇第一個(最左側)此類catch子句 。 將值V分配給所選catch子句的參數,並執行該catch子句的Block,然后可以選擇:...
(強調和省略號)。
因此,如果要執行更具體的catch
子句,則必須將其放在catch列表中的第一位。
您可以先捕獲子類異常(如果沒有),然后捕獲通用異常類,例如
try{
// something
} catch(FileNotFoundException fne){
// Handle the exception here
} catch(IOException ioe) {
// Handle the IOException here
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.