工作时,一直对try块中throw的异常对象,在catch中如何处理此异常,以及trycatchfinally完毕,程序是否就此停止还是继续运行很迷惑,于是参考网上的资料,自己写了些demo,去慢慢探索。
例1.
1 public static void main(String[] args) { 2 int i = 7; 3 int j = 0; 4 try { 5 if (j == 0) 6 throw new ArithmeticException(); 7 System.out.println("打印计算结果i/j=" + i / j); 8 } 9 catch (ArithmeticException e) { 10 System.out.println("被除数j不能等于0"); 11 } 12 System.out.println("运行结束"); 13 }
run:
被除数j不能等于0
运行结束
结论:可以看到,当try块中创建 ArithmeticException异常对象,并由throw语句将异常抛给Java运行时系统,由系统寻找匹配的异常处理器catch并运行相应异常处理代码,打印 "被除数j不能等于0",然后trycatch块结束,程序继续运行,打印"运行结束".可以看到,throw 异常对象,程序并未结束,而是继续执行。另外,我们在catch块中用输出语句打印信息,并不能很全面,直观,专业的把异常信息给显示出来。
例2.
1 public static void main(String[] args) { 2 int i = 7; 3 int j = 0; 4 try { 5 if (j == 0) 6 throw new ArithmeticException(); 7 System.out.println("打印计算结果i/j=" + i / j); 8 } 9 catch (ArithmeticException e) { 10 e.printStackTrace(); 11 } 12 System.out.println("运行结束"); 13 }
run:
java.lang.ArithmeticException
at com.westward.Demo4.main(Demo4.java:9)
运行结束
结论:通过catch块中,调用异常对象ArithmeticException的printStackTrace()方法,能够将对应的异常信息打印出来,trycatch块下面的程序继续执行。
例3.
如果我们想在try块中,j==0时,程序抛出异常,并且程序中断,可以继续看下面的demo。
1 public static void main(String[] args) { 2 int i = 7; 3 int j = 0; 4 try { 5 if (j == 0) 6 throw new ArithmeticException(); 7 System.out.println("打印计算结果i/j=" + i / j); 8 } 9 catch (ArithmeticException e) { 10 throw e; 11 } 12 System.out.println("运行结束"); 13 }
run:
Exception in thread "main" java.lang.ArithmeticException
at com.westward.Demo4.main(Demo4.java:9)
结论:通过运行结果,我们可以看到,在catch块中throw ArithmeticException对象后,throw语句将异常抛给Java运行时系统,由系统寻找匹配的异常处理器catch,由于未找到相应的异常处理器catch(没有catch或者有catch,但是类型不符合),所以异常最后抛给了jvm,并在后台打印异常信息,程序在此中断,trycatchfinally下面的程序代码不在执行。
附加:事实上,ArithmeticException为RuntimeException(运行时异常,不可查异常)的子类。而运行时异常将由运行时系统自动抛出,不需要程序员使用throw语句显示抛出。
下两例摘自:http://blog.csdn.net/hguisu/article/details/6155636
感觉真是太经典了。
例子1:
1 public static void main(String[] args) { 2 int[] intArray = new int[3]; 3 try { 4 for (int i = 0; i <= intArray.length; i++) { 5 intArray[i] = i; 6 System.out.println("intArray[" + i + "] = " + intArray[i]); 7 System.out.println("intArray[" + i + "]模 " + (i - 2) + "的值: " 8 + intArray[i] % (i - 2)); 9 } 10 } catch (ArrayIndexOutOfBoundsException e) { 11 System.out.println("intArray数组下标越界异常。"); 12 } catch (ArithmeticException e) { 13 System.out.println("除数为0异常。"); 14 } 15 System.out.println("程序正常结束。"); 16}
run:
intArray[0] = 0
intArray[0]模 -2的值: 0
intArray[1] = 1
intArray[1]模 -1的值: 0
intArray[2] = 2
除数为0异常。
程序正常结束。
相信很多man会和我有一样的疑问,怎么只抛出了ArithmeticException 异常,而未抛出ArrayIndexOutOfBoundsException异常呢?
答案是: 一旦某个catch捕获到匹配的异常类型,将进入异常处理代码。一经处理结束,就意味着整个try-catch语句结束。其他的catch子句不再有匹配和捕获异常类型的机会。也就是说,jvm运行.class文件遇到异常时,只会抛出一种异常,这时这个trycatch块就结束了。上例中,程序首先执行到i=2,除数为0的情况,java运行时程序将ArithmeticException 这个运行时异常抛给对应的catch异常捕捉器,执行异常代码,打印 "除数为0异常。"。然后此trycatch块结束,由于for循环在try块中,所以第4此循环不在执行。所以不会遇到 ArrayIndexOutOfBoundsException。 接着打印 "程序正常结束。"。
例子2:
1 public static void main(String args[]) { 2 int i = 0; 3 String greetings[] = { " Hello world !", " Hello World !! ", 4 " HELLO WORLD !!!" }; 5 while (i < 4) { 6 try { 7 // 特别注意循环控制变量i的设计,避免造成无限循环 8 System.out.println (greetings[i]); 9 i++; 10 System.out.println(i); 11 12 } catch (ArrayIndexOutOfBoundsException e) { 13 System.out.println("数组下标越界异常"); 14 } finally { 15 System.out.println("--------------------------"); 16 } 17 } 18 }
run:
会死循环。
结论:当i=3的时候,jvm执行到 System.out.println (greetings[i]);@ 会抛异常,被 ArrayIndexOutOfBoundsException捕获,执行catch块里的代码,然后执行finally,然后3<4,然后执行@处代码,然后...原因就是当System.out.println (greetings[i]);抛异常的时候,它下面的代码就不会执行了,所以i会永远等于3,3<4永远成立,进入死循环。
我们可以巧用finally如下例来避免这种情况发生。
1 public static void main(String args[]) { 2 int i = 0; 3 String greetings[] = { " Hello world !", " Hello World !! ", 4 " HELLO WORLD !!!" }; 5 while (i < 4) { 6 try { 7 // 特别注意循环控制变量i的设计,避免造成无限循环 8 System.out.println (greetings[i]); 9 10 System.out.println(i); 11 12 } catch (ArrayIndexOutOfBoundsException e) { 13 System.out.println("数组下标越界异常"); 14 } finally { 15 System.out.println("--------------------------"); 16 i++; 17 } 18 } 19 }
run:
Hello world !
0
--------------------------
Hello World !!
1
--------------------------
HELLO WORLD !!!
2
--------------------------
数组下标越界异常
--------------------------