Java異常之try,catch,finally,throw,throwsjava
你能區分異常和錯誤嗎?數組
咱們天天上班,正常狀況下可能30分鐘就能到達。可是因爲車多,人多,道路擁擠,導致咱們要花費更多地時間,這就是生活中的異常!spa
程序和生活同樣都會出現異常,先來看個異常:3d
上面出現的是算數錯誤的異常。code
在java中,除去一些編譯上的錯誤(語法)以外,就有異常和錯誤!orm
異常的定義是可本身進行處理後,程序依然能夠正常運行下去!錯誤是Java虛擬機拋出的,終止程序的運行,這就是程序和異常的區別。對象
一:什麼是異常處理?blog
異常處理機制就像咱們對平時可能遇到的意外狀況,預先想好了一些處理的辦法。也就是說,在程序執行代碼的時候,萬一發生了異常,程序會按照預約的處理辦法對異常進行處理,異常處理完畢後,程序繼續運行。字符串
java的異常處理是經過5個關鍵字來實現的:try、catch、finally、throw、throws。get
二: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.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 }
運行結果以下:
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 try 11 { 12 x++; 13 System.out.println("我有用!"); 14 } 15 catch (Exception e) { 16 System.out.println("我沒用!"); 17 } 18 finally 19 { 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 try 11 { 12 x++; 13 System.out.println("我有用!"); 14 return 6; 15 } 16 catch (Exception e) { 17 System.out.println("我沒用!"); 18 } 19 finally 20 { 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 try 11 { 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 finally 20 { 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 try 11 { 12 System.out.println("try"); 13 } 14 catch (ArithmeticException e) { 15 System.err.println("除數不能爲0!"); 16 return 6; 17 } 18 finally 19 { 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 try 11 { 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 finally 20 { 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 try 11 { 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 finally 20 { 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 try 11 { 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 finally 21 { 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 try 11 { 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 finally 21 { 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雖好用,可是若是是濫用,這樣只是會讓程序的可讀性變的很糟糕,當程序報錯,就沒法快速準確的定位了,物盡其用 人盡其才嘛!