java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > Java finally和return 执行顺序

详解Java中finally和return的执行顺序

作者:tracydragonlxy

try-catch-finally是一种针对程序运行时出错的响应手段,对于一些可以预料到的出错类型,在发生时对其进行报告和补救,这篇文章主要介绍了Java中finally和return的执行顺序,需要的朋友可以参考下

Java中finally和return的执行顺序 

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语句执行完全一样。

到此这篇关于Java中finally和return的执行顺序的文章就介绍到这了,更多相关Java finally和return 执行顺序内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文