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

Java 多次返回:哪一个设置最终返回值?,java,return,finally,Java,Return,Finally,鉴于此代码: String test() { try { return "1"; } finally { return "2"; } } 语言规范是否定义了调用test()的返回值?换句话说:在每个JVM中都是一样的吗 在Sun JVM中,返回值是2,但我想确定,这不依赖于VM。是的,定义“2”是结果。如果一个虚拟机做的不同,它就不符合规范 大多数编译器都会对此抱怨。例如,Eclipse将声明永远不会执行返回块,但这是错误的 编写这样的代

鉴于此代码:

String test() {
    try {
        return "1";
    } finally {
        return "2";
    }
}
语言规范是否定义了调用
test()
的返回值?换句话说:在每个JVM中都是一样的吗

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

是的,定义“2”是结果。如果一个虚拟机做的不同,它就不符合规范

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


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

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

String test() {
    try {
        System.exit(0);
    } finally {
        return "2";
    }
}
在这种情况下,JVM将停止,而不执行
finally


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

是,如果您从
finally
块返回了一些内容,它将替换您可能从
try
catch
块返回的任何内容

例外情况也是如此。如果在
finally
块中抛出某个异常,该异常将替换
try
catch
块中抛出的任何异常。因此,请注意不要在
finally
块中抛出某些内容,因为它可能隐藏失败的原始原因。

是的,Java语言规范对此问题非常清楚():

带有finally块的try语句通过首先执行try块来执行。还有一个选择:

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

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


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

读取程序字节码后,代码如下所示:

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";
    }
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";
    }
程序:带捕捉块:

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"; //temporary variable 
        System.out.println("finally");
        return "2";
        Exception exception;
        exception;
        System.out.println("finally");
        return "2";
    }
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";
    }

注意:使用JDK1.7编写,使用Cavaj反编译。

以上答案总结得很好,只想在这里补充一点

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

另一件有趣的事情是,如果最终使用
return
返回某个内容,则任何抛出的异常都将被丢弃。“throw e”永远无法访问。千万不要这样做,显然大学教授真的很喜欢编写这样的代码,尽管你已经回答了10年了