1. 程式人生 > >java throws和throw的區別

java throws和throw的區別

丟擲異常
丟擲異常有三種形式,一是throw,一個throws,還有一種系統自動拋異常。下面它們之間的異同。
系統自動拋異常
當程式語句出現一些邏輯錯誤、主義錯誤或型別轉換錯誤時,系統會自動丟擲異常。如:

public static void main(String[] args) { 
    int a = 5, b =0; 
    System.out.println(5/b); 
    //function(); 
}


系統會自動丟擲ArithmeticException異常:

Exception in thread "main" java.lang.ArithmeticException: / by zero
at test.ExceptionTest.main(ExceptionTest.java:62)


  再如

public static void main(String[] args) { 
    String s = "abc"; 
    System.out.println(Double.parseDouble(s)); 
    //function(); 
}


系統會自動丟擲NumberFormatException異常:

Exception in thread "main" java.lang.NumberFormatException: For input string: "abc"
at sun.misc.FloatingDecimal.readJavaFormatString(FloatingDecimal.java:1224)
at java.lang.Double.parseDouble(Double.java:510)
at test.ExceptionTest.main(ExceptionTest.java:62)


throw
throw是語句丟擲一個異常。
語法:throw (異常物件);
      如: 

throw e;


一般會用於程式出現某種邏輯時程式設計師主動丟擲某種特定型別的異常。如:

public static void main(String[] args) { 
    String s = "abc"; 
    if(s.equals("abc")) { 
      throw new NumberFormatException(); 
    } else { 
      System.out.println(s); 
    } 
    //function(); 
}


會丟擲異常:

Exception in thread "main" java.lang.NumberFormatException
at test.ExceptionTest.main(ExceptionTest.java:67)



throws
throws是方法可能丟擲異常的宣告。(用在宣告方法時,表示該方法可能要丟擲異常)
語法:[(修飾符)](返回值型別)(方法名)([引數列表])[throws(異常類)]{......}
      如:     


public void function() throws Exception{......}


當某個方法可能會丟擲某種異常時用於throws 宣告可能丟擲的異常,然後交給上層呼叫它的方法程式處理。如:

public static void function() throws NumberFormatException{ 
    String s = "abc"; 
    System.out.println(Double.parseDouble(s)); 
  } 
     
  public static void main(String[] args) { 
    try { 
      function(); 
    } catch (NumberFormatException e) { 
      System.err.println("非資料型別不能轉換。"); 
      //e.printStackTrace(); 
    } 
}


處理結果如下:
非資料型別不能轉換。
throw與throws的比較
1、throws出現在方法函式頭;而throw出現在函式體。
2、throws表示出現異常的一種可能性,並不一定會發生這些異常;throw則是丟擲了異常,執行throw則一定丟擲了某種異常物件。
3、兩者都是消極處理異常的方式(這裡的消極並不是說這種方式不好),只是丟擲或者可能丟擲異常,但是不會由函式去處理異常,真正的處理異常由函式的上層呼叫處理。

好的程式設計習慣:
1.在寫程式時,對可能會出現異常的部分通常要用try{...}catch{...}去捕捉它並對它進行處理;
2.用try{...}catch{...}捕捉了異常之後一定要對在catch{...}中對其進行處理,那怕是最簡單的一句輸出語句,或棧輸入e.printStackTrace();
3.如果是捕捉IO輸入輸出流中的異常,一定要在try{...}catch{...}後加finally{...}把輸入輸出流關閉;
4.如果在函式體內用throw丟擲了某種異常,最好要在函式名中加throws拋異常宣告,然後交給呼叫它的上層函式進行處理。


舉例:

throws E1,E2,E3只是告訴程式這個方法可能會丟擲這些異常,方法的呼叫者可能要處理這些異常,而這些異常E1,E2,E3可能是該函式體產生的。
throw則是明確了這個地方要丟擲這個異常。

如:

void doA(int a) throws IOException,{
      try{
         ......
  
      }catch(Exception1 e){
       throw e;
      }catch(Exception2 e){
       System.out.println("出錯了!");
      }
      if(a!=b)
       throw new Exception3("自定義異常");
}


程式碼塊中可能會產生3個異常,(Exception1,Exception2,Exception3)。
如果產生Exception1異常,則捕獲之後再丟擲,由該方法的呼叫者去處理。
如果產生Exception2異常,則該方法自己處理了(即System.out.println("出錯了!");)。所以該方法就不會再向外丟擲Exception2異常了,void doA() throws Exception1,Exception3 裡面的Exception2也就不用寫了。
而Exception3異常是該方法的某段邏輯出錯,程式設計師自己做了處理,在該段邏輯錯誤的情況下丟擲異常Exception3,則該方法的呼叫者也要處理此異常。

throw語句用在方法體內,表示丟擲異常,由方法體內的語句處理。
throws語句用在方法聲明後面,表示再丟擲異常,由該方法的呼叫者來處理。

throws主要是宣告這個方法會丟擲這種型別的異常,使它的呼叫者知道要捕獲這個異常。
throw是具體向外拋異常的動作,所以它是丟擲一個異常例項。

throws說明你有那個可能,傾向。
throw的話,那就是你把那個傾向變成真實的了。

如果是系統異常的話可以什麼都不用做,也可以針對方法丟擲一個異常,因為系統異常是可以被系統自動捕獲的,所以這個異常究竟是要在方法內部解決還是交給上層函式去解決其實效果是一樣的。但是我查了很多資料,即使會丟擲異常能被系統所捕獲的話還是建議針對方法寫一個throws,因為這樣在完成一個大型任務的時候可以讓別的程式設計師知道這裡會出現什麼異常。

如果是自己定義的異常,則必須要用throws丟擲該方法可能丟擲的異常,否則編譯會報錯。