一、應用背景
在實際應用中,處理異常往往需要更加復雜的處理——當一個異常出現時,單靠某個方法無法完全處理該異常,必須由幾個方法協作才能完全處理該異常,也就是說,在異常出現的當前方法中,程序只能對異常進行部分處理,還有些處理需要在方法的調用者中才能完成,所以應該再次拋出異常,讓該方法的調用者也能捕獲到異常。
為了實現這種通過多個方法協作處理同一異常的情形,可以catch塊中結合throw語句來完成。
二、應用舉例
1 代碼示例
auctiontest.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
|
public class auctiontest { private double initprice = 30.0 ; // 因為該方法中顯式拋出了auctionexception異常, // 所以此處需要聲明拋出auctionexception異常 public void bid(string bidprice) throws auctionexception { double d = 0.0 ; try { d = double .parsedouble(bidprice); } catch (exception e) { // 此處完成本方法中可以對異常執行的修復處理, // 此處僅僅是在控制臺打印異常跟蹤棧信息。 e.printstacktrace(); // 再次拋出自定義異常 throw new auctionexception( "競拍價必須是數值," + "不能包含其他字符!" ); } if (initprice > d) { throw new auctionexception( "競拍價比起拍價低," + "不允許競拍!" ); } initprice = d; } public static void main(string[] args) { auctiontest at = new auctiontest(); try { at.bid( "df" ); } catch (auctionexception ae) { // 再次捕捉到bid方法中的異常。并對該異常進行處理 system.err.println(ae.getmessage()); } } } |
auctionexception.java
1
2
3
4
5
6
7
8
9
10
|
public class auctionexception extends exception { // 無參數的構造器 public auctionexception(){} //① // 帶一個字符串參數的構造器 public auctionexception(string msg) //② { super (msg); } } |
2 運行結果
1
2
3
4
5
|
java.lang.numberformatexception: for input string: "df" at sun.misc.floatingdecimal.readjavaformatstring(floatingdecimal.java: 1224 ) at java.lang. double .parsedouble( double .java: 510 ) at auctiontest.bid(auctiontest.java: 16 ) at auctiontest.main(auctiontest.java: 39 ) |
競拍價必須是數值,不能包含其他字符!
3 結果說明
上面程序bid對應catch塊捕獲到異常后,系統打印了該異常的跟蹤棧信息,接著拋出一個auctionexception異常,通知該方法調用者再次處理auctionexception異常。
所有程序中的main方法,也就是bid方法調用者再次捕獲auctionexception異常并將該異常詳細描述信息輸出到標準錯誤輸出。
補充:java try-catch、throw和throws的幾點想法
以前寫代碼,很少用到異常,后來發現這種習慣是錯的。異常也是一種信息,并不是錯誤。
1:先寫個簡單的類:
1
2
3
4
5
6
7
8
9
10
|
package com.exception.demo; public class main { public static void main(string[] args) { main main = new main(); } public void methodtry() { } public void methodthrow() { } } |
初始環境就是這么簡答。
2:下面給方法methodtry加上方法主體:
1
2
3
4
5
6
7
8
9
|
public static void main(string[] args) { main main = new main(); main.methodtry(); } public void methodtry() { int a= 10 ; int b= 0 ; int c=a/b; } |
剛開始學代碼的時候都會寫這個方法,會拋出一個異常:
控制臺很清楚的告訴我們,被除數不能為0.但是如果我們想自己獲取這個異常,然后做些操作呢?比如說 如果這個方法體有問題,我就做一個輸出。
1
2
3
4
5
6
7
8
9
10
11
|
public void methodtry() { try { int a= 10 ; int b= 0 ; int c=a/b; system.out.println(c); } catch (exception e) { system.out.println( "這個方法體有問題:" +e.getmessage()); } } |
這個時候就用到了try-catch,手動的捕獲這個異常,然后進行我們需要的操作。畢竟異常分很多種,并不是所有的異常都是我們不需要的。
比如說對用戶登錄來說,登錄成功 登錄失敗兩種結果,登錄失敗又分為重復登錄,賬號密碼不匹配等。
我們可以把這些失敗全都寫成exception。當成功的時候就直接返回,失敗的時候拋出異常,這個可比我們寫好多返回值簡單多了。
接著說try-catch
我們手動的捕獲了這個異常。上面的代碼告訴我們,當try-catch塊中有異常時,異常后面的代碼是不會執行的。try-catch還有什么好處?回滾。
3:throw
1
2
3
4
5
6
7
|
public static void main(string[] args) { main main = new main(); main.methodthrow(); } public void methodthrow() { throw new exception( "這里有異常" ); } |
其實當我簡單的拋出個異常的時候,throw new exception()這里會報錯,現在看一個報錯信息:
顯示讓我們選擇是throws 還是try-catch。
我們寫好的throw是什么意思呢? 其實跟a/0是一個意思,都是拋出一個異常,只不過一個是jdk已經定義好的異常,被除數不能為0.一個是我們手動拋出的異常。
先用try-catch試試看
1
2
3
4
5
6
7
|
public void methodthrow() { try { throw new exception( "這里有異常" ); } catch (exception e) { system.out.println( "methodthrow:" +e.getmessage()); } } |
重點在于手動拋出異常后,我們要在catch中進行處理,在catch中寫我們的部門邏輯代碼。
4:throws
剛才我們選擇的是try-catch,現在選擇throws
1
2
3
4
5
6
7
|
public static void main(string[] args) throws exception { main main = new main(); main.methodthrow(); } public void methodthrow() throws exception { throw new exception( "這里有異常" ); } |
方法methodthrow throws exception之后,他的父類就面臨著兩種情況,要么try-catch 要么throws這個異常。這種情況跟methodthrow中手動拋出異常遇到的問題是一樣的。
看來可以這么理解:
throw是手動拋出異常,跟 被除數不能為0 數組下標越界等異常一樣,都是異常。
try-catch是在catch中手動捕獲異常,然后進行一些操作。比如說輸出異常信息,打印錯誤日志等。
throws是往上級拋出異常,我的方法methodthrow有異常,但是在這個方法中我不進行處理了,讓上級進行處理吧。然后就跑到main函數那去了。
對main函數來說,可以throws讓系統進行處理,也可以自己處理這個異常啊。
main.methodthrow()和a/0 、throw new execption()沒什么區別,都是有異常。
其實可以整體的寫:
1
2
3
4
5
6
7
8
9
10
11
|
public static void main(string[] args){ main main = new main(); try { main.methodthrow(); } catch (exception e) { system.out.println(e.getmessage()); } } public void methodthrow() throws exception { throw new exception( "這里有異常" ); } |
方法中的異常,到main函數中再進行處理。
以上為個人經驗,希望能給大家一個參考,也希望大家多多支持服務器之家。如有錯誤或未考慮完全的地方,望不吝賜教。
原文鏈接:https://blog.csdn.net/coder150806/article/details/84451225