深入浅析Java中finally语句与return的执行顺序
更新时间:2023-07-111. 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块中的异常被抑制。