JAVA学习笔记(异常处理)

关于finally块的运行顺序,在学习阶段不是很明确。查询了一些资料后,大概可以得出以下结论:“finally块是在下级函数向上级调用的函数跳转前(无论是通过return还是throw exception的方式回到调用函数)执行”,具体参照以下两个示例。

    public static void main(String[] args) {
        test t=new test();
        System.out.println(t.f());
    }   
    public String f() {
        try{
            System.out.println("try block");
            return f2();
        }
        finally{
            System.out.println("finally block");
            return "finally";
        }
    }
    public String f2(){
        System.out.println("returning");
        return "return";
    }

此时的输出结果为

try block
returning
finally block
finally

分析:try块执行,运行到f()中的return**这行,按惯例先执行return语句后半部分(用于计算return的返回值),输出returning之后,开始正式执行return语句*,将返回值*return存在一个临时区域里,并在程序正式由f()跳转回main()之前,执行finally块的语句。若finally块内有返回值,则将此返回值替换原来临时变量区内的返回值。因此最后输出的不是return而是finally。

类似的:

public static void main(String[] args) {
        test t=new test();
        try{
            System.out.println(t.f());
        }
        catch(Exception e){}
    }

    public String f() {
        try{
            System.out.println("try block");
            int a=5/0;
        }
        catch(Exception e){
            System.out.println("exception block");
            throw e;
            //return "exception"
        }
        finally{
            System.out.println("finally block");
            return "finally";
        }

输出结果仍为:

try block
exception block
finally block
finally

此时由catch块捕获并抛出异常,但finally块仍把“finally”作为返回值返回给了main函数,并由main函数打印出来。用注释掉的return部分替换原有的catch模块,结果也是一样的。

但是在finally块中修改返回值对应的变量(而不调用return语句),实际的返回值不会被修改。

public static void main(String[] args) {
        test t=new test();
        try{
            System.out.println(t.f());
        }
        catch(Exception e){}
    }

    public String f() {
        String s;
        try{
            System.out.println("try block");
            return s="return";
        }
        finally{
            System.out.println("finally block");
            s="finally";
        }
    }

输出为

try block
finally block
return

可见最后被返回的变量s没有被修改成finally。这里要说道JAVA的值传递特性。JAVA没有真正意义上(像C++)一样的引用传递。而由于string类型的不可变性,对s的修改都会采用新建一个字符串并将s引用(指针)修改到新建字符串上。然而,try块中调用的return已经反回了s的值(存在临时区域内),即return字符串对应的地址,此时将s的值修改了也没有实际作用。

考虑JAVA的值传递特性,我们可以推测,对于int之类的基础类型的返回值,在finally块修改而不return返回值变量,对函数返回值没有影响(因为return已经将变量内存储的值存入临时区域内)。但是对于class类型的变量返回值,如果在finally块内修改类的成员变量等,真正的返回值中的成员变量也会对应被修改。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值