This question already has answers here:
Why does changing the returned variable in a finally block not change the return value?
                                
                                    (7个答案)
                                
                        
                                5年前关闭。
            
                    
在准备Java认证时,我已经看到了几段这样的棘手代码。

最后的返回值是:10,但最终被调用,它将returnval修改为20。

有人可以解释为什么会这样吗?是因为catch的returnval范围不同吗?还是我在这里想念东西。

class MultipleReturn {
int getInt() {
int returnVal = 10;
try {
     String[] students = {"Harry", "Paul"};
     System.out.println(students[5]);
    }
catch (Exception e) {
    System.out.println("About to return :" + returnVal);
    return returnVal;
    }
finally {
    returnVal += 10;
    System.out.println("Return value is now :" + returnVal);
    }
return returnVal;
}

public static void main(String args[]) {
       MultipleReturn var = new MultipleReturn();
       System.out.println("In Main:" + var.getInt());
      }
}


另一段后续代码是:

class MultipleReturn {
  StringBuilder getStringBuilder() {
  StringBuilder returnVal = new StringBuilder("10");
  try {
      String[] students = {"Harry", "Paul"};
      System.out.println(students[5]);
  }
  catch (Exception e) {
      System.out.println("About to return :" + returnVal);
      return returnVal;
  }
  finally {
     returnVal.append("10");
     System.out.println("Return value is now :" + returnVal);
  }
  return returnVal;
  }

  public static void main(String args[]) {
    MultipleReturn var = new MultipleReturn();
    System.out.println("In Main:" + var.getStringBuilder());
  }
}


此处的输出是1010,这是有意义的,因为最终修改了returnval并保持不变。

任何解释都会有所帮助。

我确实知道这是编写得很差的代码,没有人在正确的头脑中应该写这样的东西。

最佳答案

在第一个示例中,finally不会做任何更改,因为已经将10标记为要在catch语句内返回的值。如果将return添加到finally块中或从return删除catch并仅保留最后一个return语句,则将获得值20。最重要的是,此处仅返回值而不是引用。

另一方面,在第二个示例中,StringBuilder是可变的,而returnVal是对该对象的引用。比带有值“ 10”的returnVal标记为要返回的值,但是在执行主方法finally块内的returnVal值打印之前,它会将returnVal的值从“ 10”更改为“ 1010”。如果您在main方法中打印returnVal,则将获得该对象的最新值“ 1010”。之所以这样工作是因为getStringBuilder返回可变的StringBuilder的引用。

07-24 21:42