1. 程式人生 > 實用技巧 >關於JAVA異常(Exception)的學習

關於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軟體開發人員
必須要能看懂。