動手動腦java異常處理
1>請閱讀並執行AboutException.java示例,然後通過後面的幾頁PPT瞭解Java中實現異常處理的基礎知識。
import javax.swing.*;
class AboutException {
public static void main(String[] a)
{
float i=1, j=0, k;
k=i/j;
System.out.println(k);
try
{
k = i/j; // Causes division-by-zero exception
//throw new Exception("Hello.Exception!"); }
catch ( ArithmeticException e)
{
System.out.println("被0除. "+ e.getMessage());
}
catch (Exception e)
{
if (e instanceof ArithmeticException)
System.out.println("被0除");
else
{
System.out.println(e.getMessage());
}
}
finally
{
JOptionPane.showConfirmDialog(null,"OK");
}
}
}
異常處理:Java中異常捕獲語句
try{用於監控可能發生錯誤的語句}
catch(異常型別 異常物件引用)
{ 用於捕獲並處理異常的程式碼 }
finally
{ //用於“善後” 的程式碼 }
不管是否有異常發生,finally語句塊中的語句始終保證被執行。
2>閱讀以下程式碼(CatchWho.java),寫出程式執行結果:
public class CatchWho {
public static void main(String[] args) {
try {
try {
throw new ArrayIndexOutOfBoundsException();
}
catch(ArrayIndexOutOfBoundsException e) {
System.out.println( "ArrayIndexOutOfBoundsException" + "/內層try-catch");
}
throw new ArithmeticException();
}
catch(ArithmeticException e) {
System.out.println("發生ArithmeticException");
}
catch(ArrayIndexOutOfBoundsException e) {
System.out.println( "ArrayIndexOutOfBoundsException" + "/外層try-catch");
}
}
}
執行結果:
ArrayIndexOutOfBoundsException/內層try-catch
發生ArithmeticException
結果分析:當內層捕獲異常並處理後,外層則不再捕獲該異常。
3>寫出CatchWho2.java程式執行的結果
public class CatchWho2 {
public static void main(String[] args) {
try {
try {
throw new ArrayIndexOutOfBoundsException();
}
catch(ArithmeticException e) {
System.out.println( "ArrayIndexOutOfBoundsException" + "/內層try-catch");
}
throw new ArithmeticException();
}
catch(ArithmeticException e) {
System.out.println("發生ArithmeticException");
}
catch(ArrayIndexOutOfBoundsException e) {
System.out.println( "ArrayIndexOutOfBoundsException" + "/外層try-catch");
}
}
}
執行結果:
ArrayIndexOutOfBoundsException/外層try-catch
結果分析:當異常未被處理時無法接受新的異常。
4>請先閱讀 EmbedFinally.java示例,再執行它,觀察其輸出並進行總結。
public class EmbededFinally {
public static void main(String args[]) {
int result;
try {
System.out.println("in Level 1");
try {
System.out.println("in Level 2");
//result=100/0; //Level 2
try {
System.out.println("in Level 3");
result=100/0; //Level 3 }
catch (Exception e) {
System.out.println("Level 3:" + e.getClass().toString());
}
finally {
System.out.println("In Level 3 finally");
}
// result=100/0; //Level 2 }
catch (Exception e) {
System.out.println("Level 2:" + e.getClass().toString());
}
finally {
System.out.println("In Level 2 finally");
}
// result = 100 / 0; //level 1 }
catch (Exception e) {
System.out.println("Level 1:" + e.getClass().toString());
}
finally {
System.out.println("In Level 1 finally");
}
}
}
執行結果:
結果分析:當外層異常未被處理時,內層異常不會被處理並且finally也不會執行,當有多層巢狀的finally語句時,異常在不同層次不同位置丟擲時,也會導致不同的finally語句塊執行順序。
5>finally語句塊一定會執行嗎?
請通過 SystemExitAndFinally.java示例程式回答上述問題
public class SystemExitAndFinally {
public static void main(String[] args)
{
try{
System.out.println("in main");
throw new Exception("Exception is thrown in main");
//System.exit(0); }
catch(Exception e)
{
System.out.println(e.getMessage());
System.exit(0);
}
finally
{
System.out.println("in finally");
}
}
}
執行結果:首先只有與finally對應的try語句得到執行的情況下finally語句才會執行,但如果finally語句之前出現例如System.exit(0) 等使Java虛擬機器停止執行的語句時finally語句也不會被執行。
備註:
-
所有派生於Throwable類的異常類,基本都沒有這些成員方法,也就是說所有的異常類都只是一個標記,記錄發生了什麼型別的異常(通過標記,編譯期和JVM做不同的處理),所有實質性的行為Throwable都具備了。
-
綜上,在一個Throwable裡面可以獲取什麼資訊?
-
獲取堆疊跟蹤資訊(原始碼中哪個類,哪個方法,第幾行出現了問題……從當前程式碼到最底層的程式碼呼叫鏈都可以查出來)
-
獲取引發當前Throwable的Throwable。追蹤獲取底層的異常資訊。
-
獲取被壓抑了,沒丟擲來的其他Throwable。一次只能丟擲一個異常,如果發生了多個異常,其他異常就不會被丟擲,這時可以通過加入suppressed異常列表來解決(JDK7以後才有)。
-
獲取基本的詳細描述資訊
-