c语言编程笔录

首页 >   > 笔记大全

笔记大全

深入浅析Java中finally语句与return的执行顺序

更新时间:2023-07-11

1. finally与return深入探究

在Java中,finally是一个代码块,该代码块在try/catch后被执行。try块中的代码通常被用于捕捉和处理异常,在这种情况下finally块会在代码try语句块之后立即执行。

当finally块存在于一个带返回值的函数中时,finally块中一旦出现了return语句,就会直接返回finally中的值,而不考虑try块和catch块中的return语句了。如下代码所示:

public class FinallyReturnTest {

    public static void main(String[] args) {

        int result = test();
        System.out.println("The result is : " + result);
    }

    public static int test() {

        try {

            return 100;
        } finally {

            return 200;
        }
    }
}

在上述代码中,try块中返回值为100,finally中返回值为200,由于finally中的return语句会覆盖掉try块中的return语句,因此最终输出200。

2. finally语句块中的异常覆盖

在finally语句块中,如果抛出了异常,那么它会覆盖掉try块或catch块中的异常,这种行为通常会引起困扰,导致程序在调试时难以发现问题。我们来看一个示例:

public class FinallyExceptionTest {

    public static void main(String[] args) {

        System.out.println(test());
    }

    public static int test() {

        try {

            int a = 1 / 0;
            return 1;
        } catch (Exception e) {

            return 2;
        } finally {

            return 3;
        }
    }
}

在上面的代码中,try块中会发生异常,因此会执行catch块中的返回值2。但是在finally块中又有一个返回值3,因此最终输出3。

实际上,在finally语句块中发生的异常会覆盖掉try/catch块中的异常,因此在实际开发中要谨慎使用finally语句块。

3. 带有System.exit的finally看看会怎样

在finally块中使用System.exit(x)语句,会直接结束程序的运行,导致try和catch块中的程序无法执行。我们来看一下如下代码:

public class FinallyExitTest {

    public static void main(String[] args) {

        System.out.println(test());
    }

    public static int test() {

        try {

            int a = 1 / 0;
            return 1;
        } catch (Exception e) {

            return 2;
        } finally {

            System.exit(0);
        }
    }
}

在上面的代码中,程序正常执行try块中的程序,但是由于finally中使用了System.exit(0),因此程序直接结束,无法输出异常信息和程序中的返回值,因此在实际开发中要避免在finally块中使用System.exit语句。

4. finally中调用方法

在finally块中调用方法,该方法中发生了异常,会导致finally中的异常被抑制。我们来看一下下面的代码:

public class FinallySubExceptionTest {

    public static void main(String[] args) {

        System.out.println(test());
    }

    public static int test() {

        try {

            int a = 1 / 0;
            return 1;
        } catch (Exception e) {

            return 2;
        } finally {

            throw new RuntimeException("finally");
        }
    }
}

在上面的代码中,try块中会发生异常,因此会执行catch块中的返回值2。但是在finally块中抛出了一个RuntimeException异常,最终输出的是finally块中抛出的异常信息,而try/catch块中的异常信息被抑制,这种行为可能会引起混淆。

总结

在Java中,finally语句块通常被用于清理资源,例如关闭文件或数据库连接。如果finally语句块中含有return或throw语句,它们将会覆盖try块或catch块中的return或throw语句。在finally语句块中抛出的异常会覆盖掉try/catch块中的异常信息,这种情况容易导致程序的调试出现问题。在finally块中过早地退出程序时,要避免使用System.exit语句,因为它会直接结束程序的运行。在finally块中调用方法,要注意方法中是否会发生异常,异常可能导致finally块中的异常被抑制。