深入理解java中的try-catch-finally

原创 2015年11月18日 10:08:40
  1. 首先讲一下异常的层次结构,就看下图吧:
    这里写图片描述
  2. 这么多异常,那我们写程序的时候都要try-catch 捕获么?答:非也

    那哪些异常需要我们try-catch捕获,哪些不需要try-catch捕获呢?
    通常,Java的异常(包括Exception和Error)分为可查的异常(checked exceptions)和不可查的异常(unchecked exceptions)。

    可查异常(编译器要求必须处置的异常):正确的程序在运行中,很容易出现的、情理可容的异常状况。可查异常虽然是异常状况,但在一定程度上它的发生是可以预计的,而且一旦发生这种异常状况,就必须采取某种方式进行处理。

    除了RuntimeException及其子类以外,其他的Exception类及其子类都属于可查异常。这种异常的特点是Java编译器会检查它,也就是说,当程序中可能出现这类异常,要么用try-catch语句捕获它,要么用throws子句声明抛出它,否则编译不会通过。
    不可查异常(编译器不要求强制处置的异常):包括运行时异常(RuntimeException与其子类)和错误(Error)。

    Exception 这种异常分两大类运行时异常和非运行时异常(编译异常)。程序中应当尽可能去处理这些异常。

    运行时异常:都是RuntimeException类及其子类异常,如NullPointerException(空指针异常)、IndexOutOfBoundsException(下标越界异常)等,这些异常是不检查异常,程序中可以选择捕获处理,也可以不处理。这些异常一般是由程序逻辑错误引起的,程序应该从逻辑角度尽可能避免这类异常的发生。
    非运行时异常 (编译异常):是RuntimeException以外的异常,类型上都属于Exception类及其子类。从程序语法角度讲是必须进行处理的异常,如果不处理,程序就不能编译通过。如IOException、SQLException等以及用户自定义的Exception异常,一般情况下不自定义检查异常。

  3. try 块:用于捕获异常。其后可接零个或多个catch块,如果没有catch块,则必须跟一个finally块。
    catch 块:用于处理try捕获到的异常。
    finally 块:无论是否捕获或处理异常,finally块里的语句都会被执行。当在try块或catch块中遇到return语句时,finally语句块将在方法返回之前被执行。在以下4种特殊情况下,finally块不会被执行:
    1)在finally语句块中发生了异常。
    2)在前面的代码中用了System.exit()退出程序。
    3)程序所在的线程死亡。
    4)关闭CPU。

  4. 下面看一下我们比较熟悉的 try catch finally语句,试试下面的代码你知道正确的执行结果么?

public class TestException {  
    public TestException() {  
    }  

    boolean testEx() throws Exception {  
        boolean ret = true;  
        try {  
            ret = testEx1();  
        } catch (Exception e) {  
            System.out.println("testEx, catch exception");  
            ret = false;  
            throw e;  
        } finally {  
            System.out.println("testEx, finally; return value=" + ret);  
            return ret;  
        }  
    }  

    boolean testEx1() throws Exception {  
        boolean ret = true;  
        try {  
            ret = testEx2();  
            if (!ret) {  
                return false;  
            }  
            System.out.println("testEx1, at the end of try");  
            return ret;  
        } catch (Exception e) {  
            System.out.println("testEx1, catch exception");  
            ret = false;  
            throw e;  
        } finally {  
            System.out.println("testEx1, finally; return value=" + ret);  
            return ret;  
        }  
    }  

    boolean testEx2() throws Exception {  
        boolean ret = true;  
        try {  
            int b = 12;  
            int c;  
            for (int i = 2; i >= -2; i--) {  
                c = b / i;  
                System.out.println("i=" + i);  
            }  
            return true;  
        } catch (Exception e) {  
            System.out.println("testEx2, catch exception");  
            ret = false;  
            throw e;  
        } finally {  
            System.out.println("testEx2, finally; return value=" + ret);  
            return ret;  
        }  
    }  

    public static void main(String[] args) {  
        TestException testException1 = new TestException();  
        try {  
            testException1.testEx();  
        } catch (Exception e) {  
            e.printStackTrace();  
        }  
    }  
}  

输出结果:这里写图片描述
当我们注释掉finally中的return语句后结果会怎么样呢?


public class TestException {  
    public TestException() {  
    }  

    boolean testEx() throws Exception {  
        boolean ret = true;  
        try {  
            ret = testEx1();  
        } catch (Exception e) {  
            System.out.println("testEx, catch exception");  
            ret = false;  
            throw e;  
        } finally {  
            System.out.println("testEx, finally; return value=" + ret);  
            return ret;  
        }  
    }  

    boolean testEx1() throws Exception {  
        boolean ret = true;  
        try {  
            ret = testEx2();  
            if (!ret) {  
                return false;  
            }  
            System.out.println("testEx1, at the end of try");  
            return ret;  
        } catch (Exception e) {  
            System.out.println("testEx1, catch exception");  
            ret = false;  
            throw e;  
        } finally {  
            System.out.println("testEx1, finally; return value=" + ret);  
            //return ret;  
        }  
    }  

    boolean testEx2() throws Exception {  
        boolean ret = true;  
        try {  
            int b = 12;  
            int c;  
            for (int i = 2; i >= -2; i--) {  
                c = b / i;  
                System.out.println("i=" + i);  
            }  
            return true;  
        } catch (Exception e) {  
            System.out.println("testEx2, catch exception");  
            ret = false;  
            throw e;  
        } finally {  
            System.out.println("testEx2, finally; return value=" + ret);  
            //return ret;  
        }  
    }  

    public static void main(String[] args) {  
        TestException testException1 = new TestException();  
        try {  
            testException1.testEx();  
        } catch (Exception e) {  
            e.printStackTrace();  
        }  
    }  
}

输出结果:这里写图片描述
总结:当finally代码里面不返回(无 return 和 throw)的时候,执行catch里面的throw语句,向上一级抛出异常。

  • fillInstackTrace

再说一个方法fillInStackTrace,fillInStackTrace每次执行的时候,会清空原来的栈内的trace信息。然后在当前的调用位置处重新建立trace信息, 所以在方法b()中printStackTrace的执行结果跟c()中的是不一样的。
b()方法被c()调用,c()被a()调用,a()被main()调用, 所以在b()中fillInStackTrace时,栈内会包含b(), a(), main()的信息;而在c()中调用fillInStackTrace时,栈内的信息会被刷新为c(), a(), main()。

版权声明:本文为博主原创文章,未经博主允许不得转载。

try_catch_finally异常处理java

  • 2013年06月11日 23:25
  • 4.36MB
  • 下载

JAVA异常处理机制的个人理解(try catch throw finally)

搜到了这篇文章 ,下面说下我自己的问题与理解。 我看完程序给出的输出是: i=2 i=1 testEx2, catch exception testEx2, finally; ret...

Java中try catch finally语句中含有return语句的执行情况(总结版)

在这里看到了try catch finally块中含有return语句时程序执行的几种情况,但其实总结的并不全,而且分析的比较含糊。但有一点是可以肯定的,finally块中的内容会先于try中的ret...
  • saytime
  • saytime
  • 2016年04月28日 16:13
  • 900

java只使用try和finally不使用catch的原因和场景

JDK并发工具包中,很多异常处理都使用了如下的结构,如AbstractExecutorService,即只有try和finally没有catch。 class X { private fin...

关于java 异常捕捉 ( try catch finally ) 执行流程

java中使用try catch finally做异常处理的情形较为常见,关于执行具体不同情况下的执行流程,在假设方法需要返回值的情况下进行分类代码说明。...

java try catch finally 执行顺序

结论: 不管有木有出现异常,finally块中代码都会执行; 当try和catch中有return时,finally仍然会执行; finally是在return后面的表达式运算后执行的(此时并没有返回...

浅析Java try....catch....finally中return语句执行顺序

浅析Java try….catch….finally中return语句执行顺序

java基础知识之(==与equals,try catch finally return ,装箱与拆箱)

一:==和equals区别在初学Java时,可能会经常碰到下面的代码: String str1 = new String("hello"); String str2 = new String("he...

Java异常处理throws,throw关键字try,catch,finally模块

ThrowableThrowable是所有的错误和异常的超类,有两大实例 Error 一般不处理,由JVM抛出 Exception 可预测可处理 —–编译时异常 :只要是Exception和其...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深入理解java中的try-catch-finally
举报原因:
原因补充:

(最多只允许输入30个字)