在准备Java认证的过程中,我看到了一些棘手的代码。
这里最后的返回值是:10,但最后调用它并将returnval修改为20.
有人可以解释为什么会这样吗?是因为捕获具有不同的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并且它会被持久化。
任何解释都会有所帮助。
我明白这是编写得很糟糕的代码,正确思想中的任何人都不应该写这样的东西。
答案 0 :(得分:1)
在第一个示例中finally
没有更改任何内容,因为10已经标记为要在catch
语句中返回的值。如果您将return
添加到finally
块或从return
删除catch
并仅保留最后一个返回语句,那么您将获得值20.最重要的是您这里只返回值而不是引用。
另一方面,在第二个示例中,StringBuilder是可变的,returnVal是对象的引用。比returnVal值和#34; 10"被标记为要返回的值,但是在main方法finally
中打印returnVal的值之前,执行块并且它会从" 10"中更改returnVal的值。至" 1010"。与在main方法中打印returnVal相比,您将获得此对象的最新值,即" 1010"。它的工作方式与此类似,因为getStringBuilder
返回StringBuilder的引用,该引用是可变的。
答案 1 :(得分:1)
这里有很多内容,但我认为它归结为在getStringBuilder版本中,returnVal对象是可变的,并且在finally子句中相同的对象发生变化,如您所观察到的那样返回“1010”。另一方面,当您向finally子句中的整数添加10时返回不同的值,该整数在内存中的地址与返回的值不同。
尝试运行以下代码,以便更好地说明。
class MultipleReturn {
int getInt() {
int returnVal = 10;
System.out.println("Identiy hash of returnVal: " + System.identityHashCode(returnVal));
try {
String[] students = { "Harry", "Paul" };
System.out.println(students[5]);
} catch (Exception e) {
System.out.println("About to return :" + returnVal);
System.out.println("Identiy hash of returnVal in catch block: " + System.identityHashCode(returnVal));
return returnVal;
} finally {
returnVal += 10;
System.out.println("Identiy hash of returnVal in finally: " + System.identityHashCode(returnVal));
System.out.println("Return value is now :" + returnVal);
}
return returnVal;
}
StringBuilder getStringBuilder() {
StringBuilder returnVal = new StringBuilder("10");
System.out.println("Identiy hash of returnVal: " + System.identityHashCode(returnVal));
try {
String[] students = { "Harry", "Paul" };
System.out.println(students[5]);
} catch (Exception e) {
System.out.println("About to return :" + returnVal);
System.out.println("Identiy hash of returnVal in catch block: " + System.identityHashCode(returnVal));
return returnVal;
} finally {
returnVal.append("10");
System.out.println("Return value is now :" + returnVal);
System.out.println("Identiy hash of returnVal in finally: " + System.identityHashCode(returnVal));
}
return returnVal;
}
static class MutableInteger {
public int val;
@Override
public String toString() {
return Integer.toString(val);
}
}
MutableInteger getMutableInt() {
MutableInteger returnVal = new MutableInteger();
returnVal.val = 10;
System.out.println("Identiy hash of returnVal: " + System.identityHashCode(returnVal));
System.out.println(System.identityHashCode(returnVal));
try {
String[] students = { "Harry", "Paul" };
System.out.println(students[5]);
} catch (Exception e) {
System.out.println("Identiy hash of returnVal in catch block: " + System.identityHashCode(returnVal));
System.out.println("About to return :" + returnVal);
return returnVal;
} finally {
returnVal.val += 10;
System.out.println("Identiy hash of returnVal in finally: " + System.identityHashCode(returnVal));
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());
System.out.println();
System.out.println("In Main:" + var.getStringBuilder());
System.out.println();
System.out.println(var.getMutableInt());
}
}
结果:
returnVal的标识哈希:1152321476 即将返回:10 catch块中的returnVal的标识哈希:1152321476 最后的returnVal的标识哈希:2116610996 现在返回值:20 在Main:10
returnVal的标识哈希:814397217 即将返回:10 catch块中的returnVal的标识哈希:814397217 现在返回值:1010 最后的returnVal的标识哈希:814397217 在Main:1010
returnVal的标识哈希:1660743788 1660743788 catch块中的returnVal的标识哈希:1660743788 即将返回:10 最后的returnVal的标识哈希:1660743788 现在返回值:20 20