關於JAVA異常(Exception)的學習
關於JAVA異常(Exception)的學習
0、異常處理機制
0.1、java中異常的作用是:增強程式健壯性。
0.2、java中異常以類和物件的形式存在。
1、java的異常處理機制
1.1、異常在java中以類和物件的形式存在。那麼異常的繼承結構是怎樣的?
我們可以使用UML圖來描述一下繼承結構。
畫UML圖有很多工具,例如:Rational Rose(收費的)、starUML等....
Object
Object下有Throwable(可丟擲的)
Throwable下有兩個分支:Error(不可處理,直接退出JVM)和Exception(可處理的)
Exception下有兩個分支:
Exception的直接子類:編譯時異常(要求程式設計師在編寫程式階段必須預先對這些異常進行處理,如果不處理編譯器報錯,因此得名編譯時異常。)。
RuntimeException:執行時異常。(在編寫程式階段程式設計師可以預先處理,也可以不管,都行。)
1.2、編譯時異常和執行時異常,都是發生在執行階段。編譯階段異常是不會發生的。
編譯時異常因為什麼而得名?
因為編譯時異常必須在編譯(編寫)階段預先處理,如果不處理編譯器報錯,因此得名。
所有異常都是在執行階段發生的。因為只有程式執行階段才可以new物件。
因為異常的發生就是new異常物件。
1.3、編譯時異常和執行時異常的區別?
編譯時異常一般發生的概率比較高。
舉個例子:
你看到外面下雨了,傾盆大雨的。
你出門之前會預料到:如果不打傘,我可能會生病(生病是一種異常)。
而且這個異常發生的概率很高,所以我們出門之前要拿一把傘。
“拿一把傘”就是對“生病異常”發生之前的一種處理方式。
對於一些發生概率較高的異常,需要在執行之前對其進行預處理。
執行時異常一般發生的概率比較低。
舉個例子:
小明走在大街上,可能會被天上的飛機輪子砸到。
被飛機輪子砸到也算一種異常。
但是這種異常發生概率較低。
在出門之前你沒必要提前對這種發生概率較低的異常進行預處理。
如果你預處理這種異常,你將活的很累。
假設你在出門之前,你把能夠發生的異常都預先處理,你這個人會更加
的安全,但是你這個人活的很累。
假設java中沒有對異常進行劃分,沒有分為:編譯時異常和執行時異常,
所有的異常都需要在編寫程式階段對其進行預處理,將是怎樣的效果呢?
首先,如果這樣的話,程式肯定是絕對的安全的。
但是程式設計師編寫程式太累,程式碼到處都是處理異常
的程式碼。
1.4、編譯時異常還有其他名字:
受檢異常:CheckedException
受控異常
1.5、執行時異常還有其它名字:
未受檢異常:UnCheckedException
非受控異常
1.6、再次強調:所有異常都是發生在執行階段的。
1.7、Java語言中對異常的處理包括兩種方式:
第一種方式:在方法宣告的位置上,使用throws關鍵字,拋給上一級。
誰呼叫我,我就拋給誰。拋給上一級。
第二種方式:使用try..catch語句進行異常的捕捉。
這件事發生了,誰也不知道,因為我給抓住了。
舉個例子:
我是某集團的一個銷售員,因為我的失誤,導致公司損失了1000元,
“損失1000元”這可以看做是一個異常發生了。我有兩種處理方式,
第一種方式:我把這件事告訴我的領導【異常上拋】
第二種方式:我自己掏腰包把這個錢補上。【異常的捕捉】
張三 --> 李四 ---> 王五 --> CEO
思考:
異常發生之後,如果我選擇了上拋,拋給了我的呼叫者,呼叫者需要
對這個異常繼續處理,那麼呼叫者處理這個異常同樣有兩種處理方式。
1.8、注意:Java中異常發生之後如果一直上拋,最終拋給了main方法,main方法繼續
向上拋,拋給了呼叫者JVM,JVM知道這個異常發生,只有一個結果。終止java程式的執行。
1 package exception; 2 3 /* 4 * 什麼是異常?異常處理機制有什麼用 5 */ 6 public class ExceptionTest01 { 7 /** 8 * 異常物件有兩個重要的方法 9 * 獲取異常簡單的描述資訊: String msg=exception.getMessage(); 10 * 列印 異常追蹤的堆疊資訊: exception.printStackTrace(); 11 * 12 */ 13 public static void main(String[] args) { 14 NullPointerException e = new NullPointerException("空指標異常"); 15 String msg = e.getMessage(); 16 System.out.println(msg); 17 //列印異常堆疊資訊 18 e.printStackTrace(); 19 System.out.println("hello world"); 20 } 21 22 }
1 package exception; 2 3 import java.io.FileInputStream; 4 import java.io.FileNotFoundException; 5 import java.io.IOException; 6 7 /* 8 * 什麼是異常?異常處理機制有什麼用 9 */ 10 public class ExceptionTest02 { 11 /** 12 * 13 try catch 子類finally 通常在其對語句塊中完成的資源進行釋放,關閉 14 finally中的語句肯定會執行 15 * 16 * 17 */ 18 public static void main(String[] args) throws IOException { 19 FileInputStream fis=null; 20 try { 21 //建立輸入 22 fis=new FileInputStream("D:\\迅雷下載\\照片\\日職.jpg"); 23 String s=null; 24 //s.toString(); 25 System.out.println("你好"); 26 } catch (FileNotFoundException e) { 27 28 e.printStackTrace(); 29 }finally{ 30 //關閉輸入流,為避免程式如果發生異常導致輸入流不關閉,建議在finally裡關閉輸入流 31 if(fis!=null){ 32 fis.close(); 33 System.out.println("try執行了"); 34 //System.exit(0); //退出java虛擬機器,後面不執行 35 } 36 } 37 38 System.out.println("try ... finally聯合使用"); 39 40 try{ 41 System.out.println("先執行"); 42 43 return;//最後執行 44 45 }finally{ 46 System.out.println("finally 第二次執行,一定會執行"); 47 48 } 49 50 51 //System.out.println("return了,這裡不會執行"); 52 } 53 54 }
finally的使用
1 package exception; 2 3 import java.io.FileInputStream; 4 import java.io.FileNotFoundException; 5 import java.io.IOException; 6 7 /* 8 * 什麼是異常?異常處理機制有什麼用 9 */ 10 public class ExceptionTest02 { 11 /** 12 * 13 try catch 子類finally 通常在其對語句塊中完成的資源進行釋放,關閉 14 finally中的語句肯定會執行 15 * 16 * 17 */ 18 public static void main(String[] args) throws IOException { 19 FileInputStream fis=null; 20 try { 21 //建立輸入 22 fis=new FileInputStream("D:\\迅雷下載\\照片\\日職.jpg"); 23 String s=null; 24 //s.toString(); 25 System.out.println("你好"); 26 } catch (FileNotFoundException e) { 27 28 e.printStackTrace(); 29 }finally{ 30 //關閉輸入流,為避免程式如果發生異常導致輸入流不關閉,建議在finally裡關閉輸入流 31 if(fis!=null){ 32 fis.close(); 33 System.out.println("try執行了"); 34 //System.exit(0); //退出java虛擬機器,後面不執行 35 } 36 } 37 38 System.out.println("try ... finally聯合使用"); 39 40 try{ 41 System.out.println("先執行"); 42 43 return;//最後執行 44 45 }finally{ 46 System.out.println("finally 第二次執行,一定會執行"); 47 48 } 49 50 51 //System.out.println("return了,這裡不會執行"); 52 } 53 54 }
面試題:
1 package exception; 2 /** 3 * 面試題 java亙古不變的語法 4 * 1.方法體中的程式碼必須遵循自上而下的順序依次執行 5 * 2.return語句一旦執行,整個方法必須結束,return 最後執行 6 * @author ASUS 7 * 8 */ 9 public class ExceptionTest03 { 10 11 public static void main(String[] args) { 12 int s=m(); 13 System.out.println(s); //結果為100 14 } 15 16 private static int m() { 17 int i=100; 18 try{ 19 return i; 20 }finally{ 21 i++; 22 } 23 } 24 25 }
自定義異常:
/*
* 異常的自定義
* 兩步:
* 1.寫一個類繼承exception或者RunctimeException
* 2.提供兩個構造方法,一個無參,一個有參
*/
1 package exception; 2 /** 3 * 自定義異常 4 * 5 * @author ASUS 6 * 7 */ 8 public class IllegalNameException extends Exception{ 9 10 public IllegalNameException() { 11 } 12 public IllegalNameException(String s){ 13 super(s); 14 } 15 }
1 package exception; 2 /** 3 * 使用者業務類,處理使用者相關的業務:例如登入,註冊等功能 4 * @author ASUS 5 * 6 */ 7 public class UserService { 8 public void register(String username ,String password) throws IllegalNameException{ 9 10 if(username==null||username.length()<=4||username.length()>=12){ 11 throw new IllegalNameException("使用者名稱錯誤,長度必須在6-12之間"); 12 13 } 14 System.out.println("註冊成功,歡迎"+username); 15 } 16 17 }
package exception; import java.util.Scanner; /** * 使用者註冊測試類 * @author ASUS * */ public class RegistTest { public static void main(String[] args) { UserService u=new UserService(); Scanner sc=new Scanner(System.in); System.out.println("歡迎來到註冊介面!!"); System.out.println("請輸入使用者名稱:"); String a = sc.next(); System.out.println("請輸入密碼:"); String b = sc.next(); try { u.register(a, b); } catch (IllegalNameException e) { System.out.println(e.getMessage()); } } }
2、什麼是UML?有什麼用?
UML是一種統一建模語言。
一種圖示式語言(畫圖的)
UML不是隻有java中使用。只要是面向物件的程式語言,都有UML。
一般畫UML圖的都是軟體架構師或者說是系統分析師。這些級別的人員使用的。
軟體設計人員使用UML。
在UML圖中可以描述類和類之間的關係,程式執行的流程,物件的狀態等.
蓋大樓和軟體開發一樣,一個道理。
蓋樓之前,會先由建築師畫圖紙。圖紙上一個一個符號都是標準符號。
這個圖紙畫完,只要是搞建築的都能看懂,因為這個圖紙上標註的這些
符號都是一種“標準的語言”。
在java軟體開發當中,軟體分析師/設計師負責設計類,java軟體開發人員
必須要能看懂。