簡體   English   中英

嘗試/捕獲與拋出異常

[英]try/catch versus throws Exception

這些代碼語句是否等效? 它們之間有什么區別嗎?

private void calculateArea() throws Exception {
    ....do something
}

private void calculateArea() {
    try {
        ....do something
    } catch (Exception e) {
        showException(e);
    }
}

是的,有一個巨大的區別 - 后者吞下了異常(無可否認地顯示它),而第一個將讓它傳播。 (我假設showException不會重新拋出它。)

所以如果你調用第一個方法並且“做某事”失敗,那么調用者將不得不處理異常。 如果你調用第二種方法並且“做某事”失敗,那么調用者根本不會看到異常......這通常是一件壞事,除非showException真正處理了異常,修復了任何錯誤,並且通常確保calculateArea達到了目的。

您可以講這個,因為你不能調用的第一個方法沒有任何捕捉Exception自己宣布你的方法可能會拋出它。

它們的不同之處在於處理Exception的責任所在。 第一個只是throws Exception ,所以它不處理它。 調用該方法的代碼需要處理Exception 第二個捕獲並處理方法內的Exception ,因此在這種情況下,調用者不必進行任何異常處理,前提是showException()本身不會引發另一個異常。

是的。 聲明throws Exception的版本將需要調用代碼來處理異常,而顯式處理它的版本則不需要。

即,簡單地說:

performCalculation();

與將處理異常的負擔轉移給調用者:

try {
    performCalculation();
catch (Exception e) {
    // handle exception
}

是的,它們之間有很大的不同。 在第一個代碼塊中,您將異常傳遞給調用代碼。 在第二個代碼塊中,您自己處理。 哪種方法正確完全取決於你在做什么。 在某些情況下,您希望代碼處理異常(例如,如果找不到文件而您想創建它),但在其他情況下,您希望調用代碼處理異常(未找到文件)並且他們需要指定一個新的或創建它)。

一般來說,您也不希望捕獲通用異常。 相反,您只想捕獲特定的,例如FileNotFoundExceptionIOException因為它們可能意味着不同的東西。

有一種特殊情況,我們不能使用 throws,我們必須使用 try-catch。 有一條規則“被覆蓋的方法不能拋出除其父類拋出的異常之外的任何額外異常”。 如果有任何額外的異常應該使用 try-catch 處理。 考慮這個代碼片段。 有一個簡單的基類

package trycatchvsthrows;

public class Base {
    public void show()
    {
        System.out.println("hello from base");
    }
}

它是派生類:

package trycatchvsthrows;

public class Derived extends Base {

    @Override
    public void show()   {
        // TODO Auto-generated method stub
        super.show();

        Thread thread= new Thread();
        thread.start();
        try {
            thread.sleep(100);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        // thread.sleep(10);
        // here we can not use public void show() throws InterruptedException 
        // not allowed
    }
}

當我們不得不調用thread.sleep()時,我們被迫使用try-catch,這里我們不能使用:

 public void show() throws InterruptedException

因為被覆蓋的方法不能拋出額外的異常。

如果您拋出異常,則子方法(覆蓋此)應處理異常

例子:

class A{
public void myMethod() throws Exception{
 //do something
}
}

A a=new A();
try{
a.myMethod();
}catch Exception(e){
//handle the exception
}

我認為“相同”是指行為。

函數的行為可以通過以下方式確定:

1) 返回值

2) 拋出異常

3) 副作用(即堆、文件系統等的變化)

在這種情況下,第一個方法傳播任何異常,而第二個方法不拋出任何已檢查的異常,並吞下大部分未檢查的異常,因此行為不同。

但是,如果你保證“做某事”永遠不會拋出異常,那么行為將是相同的(盡管在第一個版本中編譯器會要求調用者處理異常)

- 編輯 -

從 API 設計的角度來看,這些方法的契約完全不同。 此外,不建議拋出類異常。 嘗試拋出更具體的東西,讓調用者更好地處理異常。

此方法的調用者將需要捕獲此異常或在其方法簽名中聲明將其重新拋出。

private void calculateArea() throws Exception {
    // Do something
}

在下面的 try-catch 塊示例中。 這個方法的調用者不必擔心處理異常,因為它已經被處理了。

private void calculateArea() {
    try {
        // Do something

    } catch (Exception e) {
        showException(e);
    }
}

很多時候你希望調用者處理異常。 假設您讓調用者調用一個調用另一個方法的方法,該方法調用另一個方法,而不是讓每個方法處理異常,您可以在調用者處處理它。 除非,當該方法失敗時,您想在其中一種方法中執行某些操作。

private void calculateArea() throws Exception {
    ....do something
}

這會引發異常,因此調用者負責處理該異常,但如果調用者不處理異常,則可能會將其交給 jvm,這可能會導致程序異常終止。

而在第二種情況下:

private void calculateArea() {
    try {
        ....do something
    } catch (Exception e) {
        showException(e);
    }
}

這里的異常是由被調用者處理的,所以程序不會異常終止。

Try-catch是推薦的方法。

海事組織,

  • Throws 關鍵字主要與 Checked 異常一起使用以說服編譯器,但它不保證程序的正常終止。

  • 拋出關鍵字將異常處理的責任委托給
    調用者(JVM 或其他方法)。

  • 只有檢查異常才需要 Throws 關鍵字,對於未檢查異常,不使用 throws 關鍵字。

暫無
暫無

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

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