多次返回:哪一个设置最终返回值?

时间:2010-02-22 09:35:51

标签: java return finally

鉴于此代码:

String test() {
    try {
        return "1";
    } finally {
        return "2";
    }
}

语言规范是否定义了对test()的调用的返回值?换句话说:每个JVM中它总是一样的吗?

在Sun JVM中,返回值为2,但我想确定,这不依赖于VM。

7 个答案:

答案 0 :(得分:47)

是的,language spec定义结果为“2”。如果VM以不同方式执行,则不符合规范。

大多数编译器会抱怨它。例如,Eclipse将声称永远不会执行返回块,但这是错误的。

编写像这样的代码是非常糟糕的做法,不要这么做:)

答案 1 :(得分:20)

是的, Java语言规范在这个问题上非常明确(14.20.2):

  

首先执行try块,执行带有finally块的try语句。然后有一个选择:

     
      
  • 如果try块的执行正常完成,[...]
  •   
  • 如果由于抛出值V,[...]
  • 而突然完成try块的执行   
  • 如果由于任何其他原因导致try块的执行突然完成,则执行finally块。然后有一个选择:      
        
    • 如果finally块正常完成,[...]
    •   
    • 如果finally块由于原因S而突然完成,则try语句突然完成,原因为S(并且原因R被丢弃)。
    •   
  •   

答案 2 :(得分:17)

除以下示例外,将始终执行finally块:

String test() {
    try {
        System.exit(0);
    } finally {
        return "2";
    }
}

在这种情况下,JVM将停止,而不执行finally块。

因此,在您的示例中,返回值为2

答案 3 :(得分:7)

是的,如果您从finally块中返回某些内容,它将替换您从trycatch块中返回的内容。

例外也是如此。如果你在finally块中抛出一些东西,该异常将替换trycatch块中抛出的任何异常。所以要小心不要在finally块中抛出一些东西,因为它可能会隐藏失败的原因。

答案 4 :(得分:3)

读完程序的ByteCode后,代码如下:

finally块语句在try块的return语句之前被内联,因此finally块的返回首先执行,而原始的return语句从不执行。

对于计划:

String test() {
        try {
            System.out.println("try");
            return "1";
        } finally {
            System.out.println("finally");
            return "2";
        }
    }

转换为:

String test()
    {
        System.out.println("try");
        String s = "1"; //temporary variable 
        System.out.println("finally");
        return "2";
        Exception exception;
        exception;
        System.out.println("finally");
        return "2";
    }

对于程序:与catch块:

String test() {

        try {
            System.out.println("try");
            return "1";
        } catch (RuntimeException e) {
            System.out.println("catch");
            return "2";
        } finally {
            System.out.println("finally");
            return "3";
        }
    }

转换为:

String test()
    {
        System.out.println("try");
        String s = "1";
        System.out.println("finally");
        return "3";
        RuntimeException e;
        e;
        System.out.println("catch");
        String s1 = "2";
        System.out.println("finally");
        return "3";
        Exception exception;
        exception;
        System.out.println("finally");
        return "3";
    }

注意:使用JDK 1.7&使用Cavaj进行反编译。

答案 5 :(得分:0)

您可以参考以下链接。我希望它能提供所有细节:

http://www.programmerinterview.com/index.php/java-questions/will-finally-run-after-return/

它表示finally块总是会执行,即使try或catch块也有return语句。如果finally块也有return语句,那么这将覆盖try或catch块内的return语句,在这种情况下,try / catch中抛出的任何异常都将被丢弃(坏方法)。

答案 6 :(得分:0)

以上答案的总结非常好,只是想在这里再加一点。

private static int divide(int a , int b){
    try{
        return  a/b;
    }finally{
        System.out.println("In finally");
        return 1;
    }
}

如果我们通过1,0,则上述方法将抑制它抛出的异常,并仅返回结果。 话虽如此,以上代码不应在生产环境中使用。

  private static int divide(int a , int b){
        int result = 0;
        try{
            result =   a/b;
        }finally{
            System.out.println("In finally");
            result =  1;
        }

        return result;
    }

在finally块之后使用return语句将导致

Exception in thread "main" java.lang.ArithmeticException: / by zero