JAVA異常處理的拋出異常的throw和throws這兩個關鍵字的區別:throws寫在定義一個方法名的後面,表示若該方法出現異常時將異常拋給調用他的地方;throw寫在具體的方法內部,用來拋出異常進而可以被try...catch()語句捕獲;
情況一:
try {
new Exception();
System.out.println("ok");
} catch(Exception e) {
System.out.println("exception");
} finally {
System.out.println("finally");
}
打印結果:ok
Finally
說明:千萬不要以爲new Exception()會拋出異常,這裏只是簡單new了一個Exception實例而已。
情況二:
try {
throw new Exception();
System.out.println("ok");
} catch(Exception e) {
System.out.println("exception");
} finally {
System.out.println("finally");
}
結果:編譯不通過,throw new Exception();語句後面System.out.println("ok");的區域都視爲不可到達代碼段Unreachable Code
情況三:
public class TestExceptionPrint {
public static void aMethod() throws Exception {
try {
throw new Exception();
} catch(Exception e) {
System.out.println("Method Exception");
} finally {
System.out.println("finally");
}
}
public static void main(String[] args) {
try {
aMethod();
System.out.println("Main NoException!");
} catch(Exception e) {
System.out.println("exception!");
}
System.out.println("finished");
}
}
打印結果:
Method Exception
finally
Main NoException!
finished
結果說明:aMehtod裏面拋出了異常,但是由於方法裏對其有進行捕獲catch,所以異常不會傳到main方法裏,於是main方法就正常執行了。下面來看aMethod方法裏沒有對異常進行catch的情況:
情況四:
package com.yilong.scjp.test;
public class TestExceptionPrint {
public static void aMethod() throws Exception {
try {
throw new Exception();
} finally {
System.out.println("finally");
}
}
public static void main(String[] args) {
try {
aMethod();
System.out.println("Main NoException!");
} catch(Exception e) {
System.out.println("exception!");
}
System.out.println("finished");
}
}
打印結果:
finally
exception!
finished
結果說明:由於aMethod方法裏沒有對異常進行捕獲,於是異常傳遞到了Main方法裏。除此之外,還可以看到在try…catch裏面一旦捕獲到異常,那麼在該塊裏面剩下的語句就不會再被執行到(Main NoException沒有被打印),但是在出了try…catch語句塊後就又會被執行了(finished被打印了)。
還需要注意的是,異常類的結構:異常類的根類是Throwable,他的直接子類有Error,Exception,Error是系統的內部錯誤,一般程序員處理不了,如果程序中拋出Error的異常,編譯是不能通過的。而Exception則是我們可以處理的異常。Exception類裏又分兩類:一種是RuntimeException,一種是其他的Exception,RuntimeException是一種經常會出現的錯誤,這種錯誤可以catch處理,也可以不catch,而剩下的Exception則是必須進行catch的Exception。故對於上述的情況,如果在程序中拋出了異常後,既不進行捕捉,也不進行throws,那麼就會報錯,而下面的程序由於拋出的是不一定要捕捉的異常,故不會報錯:
package com.yilong.scjp.test;
public class TestExceptionPrint {
public static void aMethod() {
throw new RuntimeException();
}
public static void main(String[] args) {
try {
aMethod();
System.out.println("Main NoException!");
} catch(Exception e) {
System.out.println("exception!");
}
System.out.println("finished");
}
}
另外,捕捉異常的時候需要注意異常的“大小”,比如:Exception包括了IOException,那麼在捕獲異常的時候就必須先捕捉IOException,如果先捕捉Exception,那麼編譯期間就會報錯,因爲Exception異常已經包括了IOException。下面給出實例:
class Exc0 extends Exception {}
class Exc1 extends Exc0 {}
public class TestOutterClass {
public static void main(String args[]) {
try {
throw new Exc1();
} catch (Exc0 e0) {
System.out.println("Ex0 caught");
} catch (Exception e) {
System.out.println("exception caught");
}
}
}
打印結果:Ex0 caught
分析:如果先捕獲Exception,那麼編譯就會報錯。因爲Exc0是從Exception繼承的,所以Exception包含了Exc0;如果途中出現非Exc0的異常,那麼打印結果就是:exception caught;
補充:常見的RuntimeException有:NullPointerException, NumberFormatException(繼承自IllegalArgumentException), ArrayIndexOutOfBoundsException, StringIndexOutOfBoundsException, ClassCastException, UnSupportedOperationException, ArithmeticException, IllegalArgumentException