簡體   English   中英

當方法永遠不會拋出異常時,為什么編譯器允許拋出

[英]Why does the compiler allow throws when the method will never throw the Exception

我想知道為什么java編譯器允許在方法永遠不會拋出異常時拋出方法聲明。 因為“throws”是一種處理異常的方式(告訴調用者處理它)。

由於有兩種處理異常的方法(throws和try / catch)。 在try / catch中,它不允許捕獲未在try塊中拋出的異常,但它允許拋出一個不會拋出異常的方法。

private static void methodA() {
    try {
        // Do something
        // No IO operation here
    } catch (IOException ex) {  //This line does not compile because
                              //exception is never thrown from try
        // Handle   
    }
}

private static void methodB() throws IOException { //Why does this //compile when excetion is never thrown in function body
    //Do Something 
    //No IO operation
}

throws子句是方法契約的一部分。 它要求方法的調用者表現得好像方法可能拋出指定的異常(即捕獲異常或聲明自己的throws子句)。

方法的初始版本可能不會拋出throws子句中指定的throws ,但未來的版本可以在不破壞API的情況下拋出它(即調用該方法的任何現有代碼仍將通過編譯)。

相反它也是可能的。 如果該方法用於拋出throws子句中指定的throws ,但其未來版本不再拋出它,則應保留throws子句,以免破壞使用您的方法的現有代碼。

第一個例子:

假設您有使用methodB代碼:

private static void methodA() {
    methodB(); // doesn't have throws IOException clause yet
}

如果以后要更改methodB拋出IOExceptionmethodA將停止通過編譯。

第二個例子:

假設您有使用methodB代碼:

private static void methodA() {
    try {
        methodB(); // throws IOException
    }
    catch (IOException ex) {

    }
}

如果去掉throws從未來版本的條款methodBmethodA將不再通過編譯。

methodAprivate ,這個例子不是很有趣,因為它只能在本地使用(在同一個類中,很容易修改調用它的所有方法)。

但是,如果它變為public ,則您不知道誰使用(或將使用)您的方法,因此您無法控制因添加或刪除throws子句而可能中斷的所有代碼。

如果它是一個實例方法,即使你不拋出異常,也允許throws子句的另一個原因 - 可以重寫該方法,並且即使基類實現沒有,重寫方法也可能拋出異常。

因為簽名定義了方法的契約。 即使該方法現在不拋出IOException,也許它將來會發生,並且您希望為這種可能性做好准備。

假設您現在只為該方法提供一個虛擬實現,但是您知道,稍后,實際實現可能會拋出IOException。 如果編譯器阻止您添加此throws子句,則在提供方法的實際實現后,您將被強制重做所有對該方法的調用(遞歸)。

關鍵字throws告訴程序員可能在方法中發生IOException。 現在,如果你沒有指定try / catch,則意味着當拋出異常時,程序將停止工作,而在try / catch中,如果拋出異常則通過執行其他操作來處理它。

使用throws可讀性並指定異常的可能性,並使用try / catch告訴程序在異常的情況下該怎么做。

  1. 方法B拋出IOException,因此調用methodB的方法負責捕獲將由methodB拋出的異常。 嘗試從其他方法調用methodB,它會要求您捕獲它或重新拋出IOException。 在某個地方你必須捕獲鏈中的IOException(在try / catch塊中)。 所以你不會得到編譯時錯誤

    private void sampleMethod(){try {methodB(); } catch(IOException e){// TODO自動生成的catch塊e.printStackTrace(); }}

  2. 方法A中的try / catch確實吞下了異常,這意味着methodA負責在try / catch塊中捕獲異常。 任何java程序中的每個語句都必須是可訪問的,即每個語句必須至少可執行一次 ”因此,您將遇到編譯器錯誤,因為您的try塊沒有任何代碼導致IOException。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM