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

发布于 2024-08-23 04:51:05 字数 255 浏览 5 评论 0原文

给定以下代码:

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

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

在 Sun JVM 中,返回值为 2,但我想确定,这与 VM 无关。

Given this code:

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

Do the language specifications define the return value of a call to test()? In other words: Is it always the same in every JVM?

In the Sun JVM the return value is 2, but I want to be sure, that this is not VM-dependant.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

∞梦里开花 2024-08-30 04:51:05

是的,语言规范 定义“2”是结果。如果虚拟机以不同的方式执行此操作,则它不符合规范。

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

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

Yes, the language spec defines that "2" is the result. If a VM does it differently, it's not spec-compliant.

Most compilers will complain about it. Eclipse, for example, will claim that the return block will never be executed, but it's wrong.

It's shockingly bad practice to write code like that, don't ever do it :)

熊抱啵儿 2024-08-30 04:51:05

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

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

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

Yes, the Java Language Specification is very clear on this issue (14.20.2):

A try statement with a finally block is executed by first executing the try block. Then there is a choice:

  • If execution of the try block completes normally, [...]
  • If execution of the try block completes abruptly because of a throw of a value V, [...]
  • If execution of the try block completes abruptly for any other reason R, then the finally block is executed. Then there is a choice:
    • If the finally block completes normally, [...]
    • If the finally block completes abruptly for reason S, then the try statement completes abruptly for reason S (and reason R is discarded).
酒浓于脸红 2024-08-30 04:51:05

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

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

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

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

The finally block will always be executed except in the following example:

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

In this case, the JVM will stop, without executing the finally block.

So in your example, the return value will be 2.

小情绪 2024-08-30 04:51:05

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

对于异常也是如此。如果您在finally 块中抛出某些异常,该异常将替换在trycatch 块中抛出的任何异常。所以要小心,永远不要在finally块中扔东西,因为它可能隐藏失败的原始原因。

Yes, if you return something from the finally block, it will replace whatever you might have returned from the try or catch block.

The same is true also for exceptions. If you throw something in the finally block, that exception will replace whatever exception was thrown in the try or catch block. So be careful to never throw something in the finally block, because it may hide the original reason for a failure.

灼疼热情 2024-08-30 04:51:05

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

finally块语句内联在try块的return语句之前,因此finally块的return首先执行,而原来的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 和 1.7 编译。使用Cavaj反编译。

After reading the ByteCode of program, the code is as follows:

The finally block statements is inlined before the return statement of try block, so the return from the finally block executes first and the original return statement never does.

For Program:

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

It converts to:

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";
    }

And For program: with catch block:

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";
        }
    }

Converts to:

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";
    }

Note: Complied using JDK 1.7 & Decompiled using Cavaj.

柠檬心 2024-08-30 04:51:05

您可以参考下面的链接。我希望它能提供所有详细信息:

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

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

You can refer the below link. I hope it will provide all details:

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

It says finally block will always executes even try or catch block has return statement. And if finally block also has return statement then this will override the return statement which is inside try or catch block and in this case any exception thrown in try/catch will be discarded (bad approach).

看轻我的陪伴 2024-08-30 04:51:05

上面的答案总结得很好,只是想在这里补充一点。

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

Above answer's is very well summarized just want to add one more point here.

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

If we pass the 1,0 then the above method will suppress the exception thrown by it and just return the result.
Been said, the above code should not be used in production environment.

  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;
    }

using the return statement after the finally block will result in

Exception in thread "main" java.lang.ArithmeticException: / by zero
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文