Java';try-catch-finally机制中的返回值

Java';try-catch-finally机制中的返回值,java,coding-style,jvm,Java,Coding Style,Jvm,我刚刚遇到以下代码: public class TestFinally { public static void main(String[] args) { int returnValue = function(); System.out.println("Return value: " + returnValue); } public static int function() { try {

我刚刚遇到以下代码:

public class TestFinally {
    public static void main(String[] args) {
        int returnValue = function();

        System.out.println("Return value: " + returnValue);
    }

    public static int function() {
        try {
            return 1;
        } catch (Exception e){
            return 2;
        } finally{
            return 3;
        }
    }
}
毫无疑问,运行此代码将产生“returnvalue:3”的输出

然而,我很好奇:

  • JVM内部的机制。有人知道VM是否通过重写第一个“return1”来替换堆栈上的返回值吗?如果是的话,我在哪里可以找到更多关于这方面的信息
  • 我还没有在finally机制中找到返回的用法,finally机制是以这种方式使用的,并且在实现的 在JVM中。如果将此代码构造用作返回 错误代码,我认为有更好的方法记录错误 或者返回这些错误代码。有没有人发现这样一个词的用途 构造
  • 非常感谢

    干杯,
    Vern

    实现取决于JVM,而且有许多JVM。您可以深入了解它最终是如何实现的,但这不是唯一的方法。就语言而言,重要的是行为


    我不明白第二点——为什么
    最终存在?它并不像您所建议的那样只是返回错误代码的一种方法。您根本不必从
    内部返回。该构造的存在是为了确保某种类型的清理代码在某段代码之后运行,不管它是如何终止的,无论是正常终止还是通过异常终止或返回终止。

    我在Java语言规范中找到的内容至少定义了代码段应返回3。当然,它没有提到JVM应该如何实现这一点,以及可以进行哪些可能的优化

    第节规定:

    如果try块的执行由于任何其他原因突然完成,则执行finally块。还有一个选择:

  • 如果finally块正常完成,那么try语句由于原因R而突然完成
  • 如果finally块由于原因S而突然完成,那么try语句由于原因S而突然完成(并且原因R被丢弃)
  • 第14章的开头(更准确地说)说明了什么是正常和突然的完成。例如,具有给定值的
    返回是突然完成

    因此,在这种情况下,
    finally
    块突然完成(原因:
    返回具有给定值的
    ),因此
    try
    将出于相同的原因突然完成(返回3)。这一点在美国也得到了证实

    如果表达式的求值正常完成,并生成一个值V,那么return语句会突然完成,原因是返回值为V


    FWIW,我收到一个关于函数的警告:

    public static int function(){
        try{
            return 1;
        }catch(Exception e){
            return 2;
        }finally{
            return 3; //WARNING on this line
        }
    }
    
    它告诉我“最终块不能正常完成”。不管怎样,我仍然得到3作为返回值

    无论如何,如果我尝试另一个例子:

    public class TestFinally {
        public static void main(String[] args) {
            int returnValue = function();
    
            System.out.println("Return value: " + returnValue);
        }
    
        public static int function() {
            try {  
    
                return 1;  
                }  
            catch (Exception e) {   
                return 2;  
                }  
            finally {  
                System.out.println("i don't know if this will get printed out.");
            }
        }
    }
    
    输出将是(显然)

    我不知道JVM是如何实现它的,但最简单的方法(至少在概念上)是:

  • “try”中的返回值被推送到堆栈上
  • 然后执行“finally”块
  • 新的返回值被推送到堆栈上
  • 函数退出,返回值从堆栈中弹出,因此忽略第一个值
  • 确实是个很好的问题。

    完全解释了第439页=>

    如果表达式的计算正常完成,则生成 值V,则return语句突然完成,原因是返回 具有值V.

    前面的描述说的是“试图转移控制权”,而不仅仅是“转移控制权” 控件”,因为如果方法或构造函数中存在任何try语句(§14.20) 其try块或catch子句包含return语句,然后是any finally 这些try语句的子句将在 控件被转移到方法或构造函数的调用方突然完成一个
    最后一个子句
    可能会中断由返回语句发起的控制权转移。

    至1:不知道,我也想知道。to 2.:finally可用于做认为绝对需要做的事情,例如关闭流。我认为异常比错误代码更好,因为你已经在方法签名中看到了可能出错的地方(没有阅读任何文档),而且对于编码人员来说,忽略它们是很困难的。好吧,我不能回答第一个问题,但第二个问题似乎很明显。finally子句用于清理(如关闭流),即使代码返回,也必须进行清理。然而,在finally子句中返回是一种糟糕的做法,只是不要这样做。我不认为你需要在finnaly块中更改返回值,但是为什么他们要另一方面允许你这样做呢?但这不是一个好的做法。谢谢大家的投入。是的,我意识到我发布的问题不是那么清楚。我已经编辑并澄清了这个问题。我很好奇是否有人见过这样的代码使用,即在try块中执行返回,在finally块中使用第二个返回来覆盖try块的返回值。有人见过这种用法吗?
    i don't know if this will get printed out.
    Return value: 1