Java中finally和return的执行顺序

发布时间:2024年01月11日

try…catch…finally

try-catch-finally是一种针对程序运行时出错的响应手段,对于一些可以预料到的出错类型,在发生时对其进行报告和补救。其使用流程如下:首先执行try中的语句,如果try中的语句报错了,那么就转入对应的catch语句中执行处理异常的措施,catch后的语句中的内容是对应的错误类型。无论异常是否发生,finally中的内容一定是会被执行的,一般用来释放资源,并确保某些操作一定会执行。当try和catch中有return时,finally中代码仍然会执行。

其使用的格式如下:

try {

} catch (IOException e) {
	
} finally { // 关闭资源
    res.close();
}

1. finally语句在return语句执行之后return返回之前执行的

public class TestTryFinally {
    
    public static void main(String[] args) {
        System.out.println(test01());
    }

    private static int test01() {
        int num = 0;

        try {
            System.out.println("try block");
            num = 10;
            return num;            
        } catch (Exception e) {
            System.out.println("catch block");
        } finally {
            System.out.println("finally block");
            num = 30;
        }

        return num;
    }
}

输出结果:
try block
finally block
10

说明return语句已经执行了再去执行finally语句,不过并没有直接返回,而是等finally语句执行完了再返回结果。

public class TestTryFinally {
    
    public static void main(String[] args) {
        System.out.println(test02());
    }

    private static String test02() {

        try {
            System.out.println("try block");
            return test03();
        } catch (Exception e) {
            System.out.println("catch block");
        } finally {
            System.out.println("finally block");
        }

        return "";
    }

    private static String test03() {
        System.out.println("invoke method: test03()");

        return "method test03() return";
    }

}

输出结果:
try block
invoke method: test03()
finally block
method test03() return

说明try中的return语句先执行了但并没有立即返回,等到finally执行结束后再返回。

2. finally块中的return语句会覆盖try块中的return返回


public class TestTryFinally {
    
    public static void main(String[] args) {
        System.out.println(test04());
    }

    /*
     * finally块中的return语句会覆盖try块中的return返回
     */
    private static String test04() {
        String s = "init";

        try {
            System.out.println("try block");
            
            return "try";            
        } catch (Exception e) {
            System.out.println("catch block");
        } finally {
            System.out.println("finally block");
            return "finally";
        }

        // return s;
    }
}

输出结果:
try block
finally block
finally

这说明finally里的return直接返回了,就不管try中是否还有返回语句,这里还有个小细节需要注意,finally里加上return过后,finally外面的return s就变成不可到达语句了,也就是永远不能被执行到,所以需要注释掉否则编译器报错。

3. 如果finally语句中没有return语句覆盖返回值,那么原来的返回值可能因为finally里的修改而改变也可能不变。

import java.util.*;

public class TestTryFinally {
    public static void main(String[] args) {
    	System.out.println(test01());
        System.out.println("######################");
        System.out.println(getMap().get("key").toString());
    }
    
    private static int test01() {
        int num = 0;

        try {
            System.out.println("try block");
            num = 10;
            return num;            
        } catch (Exception e) {
            System.out.println("catch block");
        } finally {
            System.out.println("finally block");
            num = 30;
        }

        return num;
    }
    
    public static Map<String, String> getMap() {
        Map<String, String> map = new HashMap<String, String>();
        map.put("KEY", "INIT");
         
        try {
            map.put("KEY", "TRY");
            return map;
        } catch (Exception e) {
            map.put("KEY", "CATCH");
        } finally {
            map.put("KEY", "FINALLY");
            map = null;
        }
         
        return map;
    }
}

我们先来看一下AI(ChatGPT3.5,Bard和文心一言3.5)给出的答案是什么。我们可以看到ChatGPT文心一言给出的结果是:程序会抛出NullPointerException异常,而Bard给出的结果为:TRY
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
而实际运行代码,我们得到的结果为:FINALLY

输出结果:
try block
finally block
10
######################
try block
finally block
finally

为什么test01()finally里的num = 30;并没有起到作用,而getMap()finallymap.put("key", "finally");起了作用,而map = null;却没起作用呢?这就是Java到底是传值还是传址的问题了,简单来说就是:Java中只有传值没有传址,这也是为什么map = null这句不起作用。

4. try块里的return语句在异常的情况下不会被执行

    public static void main(String[] args) {
        System.out.println(test06());
    }

    private static int test05() {
        int num = 10;

        try {
            System.out.println("try block");
            num = 5 / 0;

            return num;
        } catch (Exception e) {
            System.out.println("catch block");
            num += 20;
        } finally {
            System.out.println("finally block");

            num += 30;
        }

        return num;
    }

输出结果:
try block
catch block
finally block
60

try语句块中发生了除0异常,所以try中的return不会被执行到,而是接着执行捕获异常的catch语句和最终的finally语句,此时两者对num的修改都影响了最终的返回值。

5. 当发生异常后,catch中的return执行情况与未发生异常时try中return的执行情况完全一样

    public static void main(String[] args) {
        System.out.println(test06());
    }

    private static int test06() {
        int num = 10;

        try {
            System.out.println("try block");
            num = 5 / 0;

            return num;
        } catch (Exception e) {
            System.out.println("catch block");
            num += 20;
            return num;
        } finally {
            System.out.println("finally block");

            num += 30;
        }

        // return num;
    }

输出结果:
try block
catch block
finally block
30

说明了发生异常后,catch中的return语句先执行,确定了返回值后再去执行finally块,执行完了catch再返回,finally里对num的改变对返回值无影响,原因同前面一样,也就是说情况与try中的return语句执行完全一样。

文章来源:https://blog.csdn.net/tracydragonlxy/article/details/135411399
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。