zoukankan      html  css  js  c++  java
  • trycatch之catch对捕获异常的处理及后续代码的执行的探索

    工作时,一直对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
       --------------------------
       数组下标越界异常
       --------------------------

  • 相关阅读:
    第一章 Shell基础知识
    keepalived与LVS实现高可用
    集群简介
    基于NFS v4版本搭建NFS服务器
    LDAP安装步骤
    Nginx配置阿里云https服务
    zabbix基础
    Apache、Nginx和Tomcat之虚拟主机配置
    标准盒模型和怪异盒模型的区别
    js中数组扁平化处理
  • 原文地址:https://www.cnblogs.com/westward/p/5164952.html
Copyright © 2011-2022 走看看