java提高(1)---異常


異常

 

一.異常與錯誤的區別

     再講異常之前我們就應該要知道異常和錯誤的區別

     Error類和Exception類的父類都是throwable類,他們的區別是:

     Error類一般是指與虛擬機相關的問題,如系統崩潰,虛擬機錯誤,內存空間不足,方法調用棧溢等。對於這類錯誤的導致的應用程序中斷,

僅靠程序本身無法恢復和和預防,遇到這樣的錯誤,建議讓程序終止。

    Exception類表示程序可以處理的異常,可以捕獲且可能恢復。遇到這類異常,應該盡可能處理異常,使程序恢復運行,而不應該隨意終止異常。

 

二.異常的體現分類

   1.checked 異常檢查期異常 java.lang.Excetion 在編譯期需要人工處理否則編譯失敗:Exception的子類除了運行期異常都是檢查期異常

   2.Checked異常運行時異常 java.lang.RuntimeException 不需要處理的直接能編譯通過:所有的RuntimeException以及其子類都是運行異常

   舉例:運行期異常

    結果:運行期異常,當你敲好代碼時不會報錯,而當你運行時才會報除數不能為0的錯誤

   舉例:檢查期異常:

   結果:檢查期異常,當你編譯的時候就會報錯,一定要拋出異常編譯才能通過

 三.異常的處理機制

      Java語言主要依賴於 try  catch  finally  throws  throw  五個關鍵字來描述異常

 1) 在發生異常的地方直接處理

    使用try catch finally  直接處理異常

     a)  try-catch-finally結構中try塊是必須有的,catchfinally塊為可選,但兩者至少必須出現其中之一。

     b) catch  可以同時出現多個,但一個異常最多捕獲一個catch,而且catch的順序是從上往下

     c) finally  無論是否捕獲異常都會執行的一行代碼

演示1:try異常

 1 public class TestException {
 2         public static void main(String[] args) {
 3              int c = 0;
 4                 try
 5                 {
 6                     int a = 3;
 7                     int b = 0;
 8                     // 這塊代碼出現了異常
 9                      c = a / b;
10                     // 那么異常之后的代碼都不會被執行
11                     System.out.println("Hello World");
12                 }
13                 catch (ArithmeticException e)
14                 {
15                     System.out.println("除數不能為零");
16                 }
17                 finally
18                 {
19                     //不管有沒有發生異常,finally語句塊都會被執行
20                     System.out.println("Welcome");
21                 }
22                 System.out.println(c);
23                 // 當b為0時,有異常,輸出為c的初始值0
24         }
25     }
26    //輸出結果:除數不能為零  Welcome   0
try異常

演示2:帶有return的異常

 1 import java.io.FileInputStream;
 2 import java.io.FileNotFoundException;
 3  public class DemoException {
 4      public static void main(String[] args) {
 5             int a=test3();
 6             System.out.println(a);    
 7   }
 8      @SuppressWarnings("finally")
 9      public static int  test3(){
10              try {
11              System.out.println(9 / 0);
12              return 1;
13              } catch (Exception e) {
14                System.out.println("呵呵");
15                 return 2;
16             }finally{  
17              System.out.println("哈哈");
18              return 3;
19        }
20     }
21  }
22  //輸出結果 "呵呵""哈哈" 3

 

得出結論作用范圍   return  終止整個方法體,但在finally出現之前  return是老大  finally 作用范圍> return

2)將異常拋給調用者讓調用者處理 

1   //throws在方法體頭部通過聲明  拋出異常...
2     public void dealFile() throws FileNotFoundException{
3         FileInputStream fis =new FileInputStream("C:/name.txt");
4      }
5    //那么那么上面調用這個方法可以選擇是繼續拋出,還是捕獲異常

案例一:通過throws拋出異常,調用者直接捕獲拋出的異常

 1 public class TestException {
 2      public static void main(String[] args) {
 3                  try {
 4                       Test3();  //這里選擇直接捕獲異常,而不是在拋出異常
 5                  } catch (NumberFormatException e) {
 6                      System.err.println("非數據類型不能轉換。");
 7                 } //System.err.println();這種輸出方式可以輸出錯誤的消息,在控制台呈現紅色。
 8            }
 9        
10             public static void Test3() throws NumberFormatException{  
11                  String s = "abc";  
12                 System.out.println(Double.parseDouble(s));  
13              }  
14     }
throws異常

運行結果:

   非數據類型不能轉換。

注意使用Throws是的限制

兩小原則

 使用throws 聲明拋出異常一個限制

 子類繼承父類重寫父類的方法

 子類拋出的異常必須比父類少

 子類拋出的異常必須比父類小

 兩小原則是針對檢查期異常的,運行期異常不遵循這個規則(RuntimeException 以及子類)

案例二:通過throw拋出異常

 1 public class TestException {
 2      public static void main(String[] args) {
 3          String s = "abc";  
 4                if(s.equals("abc")) {  
 5                      throw new NumberFormatException("不能相等");
 6                  } else {  
 7                      System.out.println(s);  
 8                 }  
 9              }  
10     }
throw異常

運行結果如下:

面試題:Throw Throws有什么區別?

 Throw語句是用在方法體內表示拋出的異常由方法體內的語句處理

 Throws  語句是在方法聲明之后拋出異常表示在拋出的異常交給調用者處理

 Throws 要么使用try –catch –finally 處理要么繼續拋出

 四.自定義異常 

   所謂自定義異常,通常就是定義一個類,去繼承Exception類或者它的子類。因為異常必須直接或者間接地繼承自Exception類。

  通常情況下,會直接繼承自Exception類,一般不會繼承某個運行時的異常類。

  自定義異常可以用於處理用戶登錄錯誤,用戶輸入錯誤提示等。

   自定義異常需要遵循以下步驟

  1. 繼承RuntimeExcetion  或者Exception
  2. 寫一個無參的構造函數
  3. 寫一個String類型的構造函數

 舉例:自定義異常:

public class MyException extends Exception
{
    public MyException()
    {
        super();
    }    
    public MyException(String message)
    {
        super(message);
    }
}

一種處理異常方式

public class ExceptionTest4
{

    public void method(String str) throws MyException
    {
        if(null == str)
        {
            throw new MyException("傳入的字符串參數不能為null!");
        }
        else
        {
            System.out.println(str);
        }
    }
    public static void main(String[] args) throws MyException //異常處理方式1,不斷向外拋出
    {
        ExceptionTest4 test = new ExceptionTest4();
        test.method(null);
    }
}

另一種異常處理方式:

 1 public class ExceptionTest4
 2 {
 3 
 4     public void method(String str) throws MyException
 5     {
 6         if (null == str)
 7         {
 8             throw new MyException("傳入的字符串參數不能為null!");
 9         }
10         else
11         {
12             System.out.println(str);
13         }
14     }
15 
16     public static void main(String[] args)
17     {
18         //異常處理方式2,采用try...catch語句
19         try
20         {
21             ExceptionTest4 test = new ExceptionTest4();
22             test.method(null);
23 
24         }
25         catch (MyException e)
26         {
27             e.printStackTrace();
28         }    
29         finally
30         {
31             System.out.println("程序處理完畢");
32         }
33 
34     }
35 }

最后說一句,try-catch-finally雖好用,但是如果是濫用,這樣只是會讓程序的可讀性變的很糟糕,當程序報錯,就無法快速准確的定位了。

如果有個別地方寫的不到位或者不夠完善希望大家多多指點,看了有不明白的地方也可以留言,我也會盡快幫助解答。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM