java異常之try,catch,finally,throw,throws
你能區分異常和錯誤嗎?
我們每天上班,正常情況下可能30分鐘就能到達。但是由于車多,人多,道路擁擠,致使我們要花費更多地時間,這就是生活中的異常!
程序和生活一樣都會出現異常,先來看個異常:
上面出現的是算數錯誤的異常。
在java中,除去一些編譯上的錯誤(語法)之外,就有異常和錯誤!
異常的定義是可自己進行處理后,程序依然可以正常運行下去!錯誤是Java虛擬機拋出的,終止程序的運行,這就是程序和異常的區別。
一:什么是異常處理?
異常處理機制就像我們對平時可能遇到的意外情況,預先想好了一些處理的辦法。也就是說,在程序執行代碼的時候,萬一發生了異常,程序會按照預定的處理辦法對異常進行處理,異常處理完畢后,程序繼續運行。
java的異常處理是通過5個關鍵字來實現的:try、catch、finally、throw、throws。
二:java異常類的層次結構
三.常見的異常類型
Exception 異常層次結構的根類
ArithmeticException 算數錯誤情形
ArrayIndexOutOfBoundsException 數組下標越界
NullPointerException 嘗試訪問null對象成員
ClassNotFoundException 不能加載所需的類
InputMismatchException 欲得到的數據類型與實際輸入的類型不匹配
IllegalArgumentException 方法接受到非法參數
ClassCastException 對象強制類型轉換出錯
NumberFormatException 數字格式轉換異常
四.具體實例
1 package Test; 2 3 import java.util.Scanner; 4 5 public class Test_Test { 6 public static void main(String[] args) { 7 Scanner input =new Scanner(System.in); 8 System.out.); 9 try {10 int num1=input.nextInt();11 System.out.println("請輸入除數:");12 int num2=input.nextInt();13 System.out.println(String.format("%d / %d = %d",14 num1, num2, num1 / num2));15 }catch (Exception e) {16 System.err.println("出現錯誤:被除數和除數必須是整數,"+17 "除數不能為零。");18 System.out.println(e.getMessage());19 }20 }
運行結果如下:
System.err.println();這種輸出方式可以輸出錯誤的消息,在控制臺呈現紅色。
System.out用于正常的輸出,也就是程序真正想輸出的內容。而System.err用于出錯信息的輸出,也就是你本來不期待看到的東西。
System.out.println(e.getMessage());
這行的作用是——返回該錯誤的詳細信息的字符串。
1 package Test; 2 3 import java.util.Scanner; 4 5 public class Test_Test { 6 public static void main(String[] args) { 7 Scanner input =new Scanner(System.in); 8 System.out.println("請輸入被除數:"); 9 try {10 int num1=input.nextInt();11 System.out.println("請輸入除數:");12 int num2=input.nextInt();13 System.out.println(String.format("%d / %d = %d",14 num1, num2, num1 / num2));15 }catch (Exception e) {16 System.err.println("出現錯誤:被除數和除數必須是整數,"+17 "除數不能為零。");18 System.out.println(e.getMessage());19 }20 finally{21 System.out.println("Thanks");22 }23 }24 }
運行結果如下:
try-catch-finally 程序塊的流程大致分為兩種情況:
try-catch-finally結構中try塊是必須有的,catch和finally塊為可選,但兩者至少必須出現其中之一。
1 package Test; 2 3 import java.util.InputMismatchException; 4 import java.util.Scanner; 5 6 public class Test_Test { 7 public static void main(String[] args) { 8 Scanner input =new Scanner(System.in); 9 System.out.println("請輸入被除數:");10 try {11 int num1=input.nextInt();12 System.out.println("請輸入除數:");13 int num2=input.nextInt();14 System.out.println(String.format("%d / %d = %d",15 num1, num2, num1 / num2));16 }catch (InputMismatchException e) {17 System.err.println("被除數和除數必須是整數。");18 }19 catch (ArithmeticException e) {20 System.err.println("除數不能為零。");21 }22 catch (Exception e) {23 System.err.println("其他未知異常。");24 System.out.println(e.getMessage());25 }26 finally{27 System.out.println("Thanks");28 }29 }30 }
運行結果如下:
所以,在寫異常處理的時候,一定要把異常范圍小的放在前面,范圍大的放在后面,Exception這個異常的根類一定要剛在最后一個catch里面,如果放在前面或者中間,任何異常都會和Exception匹配的,就會報已捕獲到...異常的錯誤。
下面是try-catch-finally中包含return的情況:
正常按程序順序執行即可。
1 package Test; 2 3 public class Test_Test { 4 public static void main(String[] args) { 5 Test1(); 6 } 7 8 public static int Test1(){ 9 int x = 1;10 try11 {12 x++;13 System.out.println("我有用!");14 }15 catch (Exception e) {16 System.out.println("我沒用!");17 }18 finally19 {20 ++x;21 System.out.println("我也有用!");22 }23 return 2;24 }25 }
運行結果如下:
程序執行try塊中return之前(包括return語句中的表達式運算)代碼;
再執行finally塊,最后執行try中return;
finally塊之后的語句return,因為程序在try中已經return所以不再執行。
1 package Test; 2 3 public class Test_Test { 4 public static void main(String[] args) { 5 Test1(); 6 } 7 8 public static int Test1(){ 9 int x = 1;10 try11 {12 x++;13 System.out.println("我有用!");14 return 6;15 }16 catch (Exception e) {17 System.out.println("我沒用!");18 }19 finally20 {21 ++x;22 System.out.println("我也有用!");23 }24 return 2;25 }26 }
運行結果如下:
程序先執行try,如果遇到異常執行catch塊,
有異常:則執行catch中return之前(包括return語句中的表達式運算)代碼,再執行finally語句中全部代碼,
最后執行catch塊中return. finally之后也就是4處的代碼不再執行。
無異常:執行完try再finally再return.
1.有異常的情況:
1 package Test; 2 3 public class Test_Test { 4 public static void main(String[] args) { 5 Test1(); 6 } 7 8 public static int Test1(){ 9 int x = 5;10 try11 {12 int num=x / 0;13 System.out.println(num);14 }15 catch (ArithmeticException e) {16 System.err.println("除數不能為0!");17 return 6;18 }19 finally20 {21 ++x;22 System.out.println("finally");23 }24 return 2;25 }26 }
運行結果如下:
2.無異常的情況:
1 package Test; 2 3 public class Test_Test { 4 public static void main(String[] args) { 5 Test1(); 6 } 7 8 public static int Test1(){ 9 int x = 5;10 try11 {12 System.out.println("try");13 }14 catch (ArithmeticException e) {15 System.err.println("除數不能為0!");16 return 6;17 }18 finally19 {20 ++x;21 System.out.println("finally");22 }23 return 2;24 }25 }
運行結果如下:
程序執行try塊中return之前(包括return語句中的表達式運算)代碼;
再執行finally塊,因為finally塊中有return所以提前退出。
1 package Test; 2 3 public class Test_Test { 4 public static void main(String[] args) { 5 Test1(); 6 } 7 8 public static int Test1(){ 9 int x = 5;10 try11 {12 int num = x / 0;13 System.out.println("try");14 return 3;15 }16 catch (ArithmeticException e) {17 System.err.println("除數不能為0!");18 }19 finally20 {21 ++x;22 System.out.println("finally");23 return 2;24 }25 }26 }
運行結果如下:
程序執行catch塊中return之前(包括return語句中的表達式運算)代碼;
再執行finally塊,因為finally塊中有return所以提前退出。
1 package Test; 2 3 public class Test_Test { 4 public static void main(String[] args) { 5 Test1(); 6 } 7 8 public static int Test1(){ 9 int x = 5;10 try11 {12 int num = x / 0;13 System.out.println("try");14 }15 catch (ArithmeticException e) {16 System.err.println("除數不能為0!");17 return 4;18 }19 finally20 {21 ++x;22 System.out.println("finally");23 return 2;24 }25 }26 }
運行結果如下:
程序執行try塊中return之前(包括return語句中的表達式運算)代碼;
有異常:執行catch塊中return之前(包括return語句中的表達式運算)代碼;
則再執行finally塊,因為finally塊中有return所以提前退出。
無異常:則再執行finally塊,因為finally塊中有return所以提前退出。
1.有異常
1 package Test; 2 3 public class Test_Test { 4 public static void main(String[] args) { 5 Test1(); 6 } 7 8 public static int Test1(){ 9 int x = 5;10 try11 {12 int num = x / 0;13 System.out.println("try");14 return 4;15 }16 catch (ArithmeticException e) {17 System.err.println("除數不能為0!");18 return 4;19 }20 finally21 {22 ++x;23 System.out.println("finally");24 return 2;25 }26 }27 }
運行結果如下:
2.無異常
1 package Test; 2 3 public class Test_Test { 4 public static void main(String[] args) { 5 Test1(); 6 } 7 8 public static int Test1(){ 9 int x = 5;10 try11 {12 // int num = x / 0;13 // System.out.println("try");14 return 4;15 }16 catch (ArithmeticException e) {17 System.err.println("除數不能為0!");18 return 4;19 }20 finally21 {22 ++x;23 System.out.println("finally");24 return 2;25 }26 }27 }
運行結果如下:
最終結論:任何執行try 或者catch中的return語句之前,都會先執行finally語句,如果finally存在的話。
如果finally中有return語句,那么程序就return了,所以finally中的return是一定會被return的,
編譯器把finally中的return實現為一個warning。
拋出異常有三種形式,一是throw,一個throws,還有一種系統自動拋異常。
系統拋出異常:
1 package Test;2 3 public class Test2 {4 public static void main(String[] args) {5 int a = 5, b =0; 6 System.out.println(5/b); 7 }8 9 }
運行結果如下:
throw拋出異常:
throw是語句拋出一個異常。
語法:throw (異常對象);
1 package Test; 2 3 public class Test2 { 4 public static void main(String[] args) { 5 String s = "abc"; 6 if(s.equals("abc")) { 7 throw new NumberFormatException(); 8 } else { 9 System.out.println(s); 10 } 11 }12 13 }
運行結果如下:
throws是方法可能拋出異常的聲明。(用在聲明方法時,表示該方法可能要拋出異常)
語法:[(修飾符)](返回值類型)(方法名)([參數列表])[throws(異常類)]{......}
1 package Test; 2 3 public class Test2 { 4 public static void main(String[] args) { 5 try { 6 Test3(); 7 } catch (NumberFormatException e) { 8 System.err.println("非數據類型不能轉換。"); 9 }10 }11 12 public static void Test3() throws NumberFormatException{ 13 String s = "abc"; 14 System.out.println(Double.parseDouble(s)); 15 } 16 }
運行結果如下:
如果在一個方法體中拋出了異常,那么我們就可以通過throws——聲明異常來通知調用者,非常方便。
throws表示出現異常的一種可能性,并不一定會發生這些異常;throw則是拋出了異常,執行throw則一定拋出了某種異常對象。
最后說一句,try-catch-finally雖好用,但是如果是濫用,這樣只是會讓程序的可讀性變的很糟糕,當程序報錯,就無法快速準確的定位了,物盡其用 人盡其才嘛!
新聞熱點
疑難解答