1. 程式人生 > >java學習筆記七——異常處理

java學習筆記七——異常處理

                                ****Java異常處理****

異常:程式中出現錯誤導致中斷了正常的指令流。
編譯錯誤邏輯錯誤都不是異常,異常是可以正常執行的程式在執行中可能發生的錯誤。沒有異常處理的程式碼可能非正常結束出現嚴重的問題
常見的異常比如:
陣列越界 (運算元超出範圍)整數除0 網路中斷 要開啟的檔案不存在
超出了某次資源限制如記憶體不夠等
如果用if-else作為處理異常的方法的話,必須要仔細考慮可能出現的所有的錯誤型別以及對應的處理措施。增加了程式碼的複雜性,可讀性變差。
If(a==0){輸出錯誤資訊}
Else 計算出發運算

Java try-catch

語句處理錯誤:
異常的處理使得程式可以發現異常並處理異常,正常退出程式
try{
程式程式碼
}catch(異常型別1 異常的變數名1){
程式程式碼
}catch(異常型別2 異常的變數名2){
程式程式碼
}finally{
程式程式碼
}
與傳統if-else的異常處理方式相比的優點:
1、 把錯誤程式碼從常規程式碼中分離出來
2、 把錯誤傳播給呼叫堆疊
3、 系統提供對一些難以預料的錯誤的捕獲和處理
4、 將錯誤型別分類
5、 克服了傳統方法錯誤資訊有限的問題

Java遇到異常有兩種方式try-catch捕獲並處理異常

,一個try可以匹配多個catch;throw exception丟擲異常

Try-catch-finally:
try{
程式程式碼
}catch(異常型別1 異常的變數名1){
程式程式碼
}catch(異常型別2 異常的變數名2){
程式程式碼
}finally{
程式程式碼
}
還是這個結構,try裡的程式程式碼執行的時候如果出現異常就會丟擲給外面,看緊接著的catch們有沒有可以匹配的,匹配上的就進行對應catch的異常處理,匹配不上的就一層層回找,直到main函式如果還沒有進行處理,就呼叫相關函式輸出錯誤資訊(就是常見的那種紅字);
Finally

中的程式碼是無論如何都會執行的程式碼,不管有沒有異常什麼異常有沒有匹配,都要執行這部分程式碼。所以有非常重要的比如釋放記憶體等,為防止在異常出現後不能繼續執行應放在finally裡

注意:
1、try catch finally不能單獨用,以三種組合形式出現:try-catch-finally try-catch try-finally
2、finally跟宣告常量的那個final沒有關係
3、多個catch塊的時候,最多會和其中一個匹配,其他的就不再執行
4、try catch finally三個部分的作用域各自獨立
5、如果把一個異常類和其子類都放在catch裡,那麼應該把子類放在前面,否則永遠到不了子類
舉個例子:

try{
                String[] A={"1","2"};
                A[10]="77";
                int a = 10/0;
                System.out.println("Another");
            }catch(ArithmeticException e){
                System.out.println("異常是:"+e.getMessage());
            }
            catch(IndexOutOfBoundsException e){
                System.out.println("異常是:"+e.getMessage());
            }

輸出:
異常是:10
//後面的一個異常和一個輸出語句均沒有執行

Throws宣告異常和丟擲異常
Throws在方法宣告的時候說明該方法會丟擲的各種異常,並說明該方法會丟擲異常但不會處理異常
//宣告異常:一個方法不處理他產生的異常,而是沿著呼叫層次向上傳遞,由呼叫他的方法來處理這些異常

宣告異常的方法:
<訪問許可權修飾符><返回值型別><方法名>(引數列表) throws 異常列表{}
比如:
public void test(int a) throws MyException{}
關鍵詞throws後面是該方法可能產生但不處理的異常型別,之間用,隔開
此時這中異常交由呼叫該方法的方法處理,或者交由系統處理,如果直到main函式還不能處理,程式就要異常終止了

舉個例子:

public int  compute(int x) throws 
                                 ArithmeticException e)
{  return z=100/x;}
public method1()
{   int x;
     try  { x=System.in.read();
               compute(x);}
     catch(IOException ioe)
     {   System.out.println(“read error”); }
     catch(ArithmeticException e)
     {   System.out.println(“devided by 0”); }
}```



虛擬機器(系統)處理的異常
對於程式中必須由系統處理的異常,可以使用throws語句丟擲異常交由系統處理
比如:

public class ThrowsTest1{
public static void main(String args[])throws IOException{
FileInputStream fis=new FileInputStream(“a3.txt”);
}
}
“`

上述程式碼會在異常時由系統丟擲異常
也可在程式碼中用throw關鍵字顯式的丟擲異常:throw 異常物件
程式會在throw語句時立刻終止,轉而尋找try-catch,所以緊跟throw後面的程式碼沒有意義,不會執行
//注意throws 和throw的區別啊

Java定義的標準異常類
按照編譯時是否受檢分為兩類:
非受檢異常(unchecked exception):只能在程式執行時被檢測到,不能在編譯時被檢測到,如RuntimeException及其子類
受檢異常(checked exception):編譯時就能被檢測

建立自己的異常類:
Java的Exception類:一般性程式故障,一般由使用者程式碼或類庫生成並丟擲,Java程式需要對他們處理
Exception類的兩個構造方法:
Public Exception();
Public Exception(String s);s一般是要丟擲的錯誤資訊

該類常用的方法:
Public String toString();一般返回描述當前異常類資訊的字串
Public void printStackTrace();一般是在螢幕上輸出呼叫堆疊的軌跡,常見的紅字報錯就是這個

所以對異常物件e獲取異常資訊的方法有三種:
1. e.toString( );
2. e.getMessage( );
3. e.printStackTrace( );
不過輸出的格式不一樣

所以寫自己的異常類的時候可以讓自己的異常類繼承自Exception類,那麼很多方法就可以覆蓋或者過載或者用super直接呼叫了,然後其他會丟擲這類異常的方法只要聲明瞭throws該類的類名,在異常的情況下throw丟擲即可(或者處理)