java - 在这两种情况下,java字符串为何有不同的返回值

为什么String和String缓冲区有不同的输出,


public class ReturnValueFromTryCatchFinally {



 public static void main(String[] args) {


 System.out.println(methodReturningValue());


 }



 static StringBuffer methodReturningValue() {


 StringBuffer buffer = new StringBuffer();


 try {


 buffer.append("aa");


 return buffer;


 }


 catch (Exception e) {


 buffer.append("bbb");


 return buffer;


 }


 finally {


 buffer.append("vvvv");


 }



 }



 static String methodReturningValue1() {


 String buffer = new String();


 try {


 buffer=buffer.concat("aa");


 return buffer;


 }


 catch (Exception e) {


 buffer=buffer.concat("bbb");


 return buffer;


 }


 finally {


 buffer=buffer.concat("vvvv");


 }



 }



}



对于用户定义的对象,它的行为与String相同,

时间:

return buffer; 记住实例返回。 buffer=buffer.concat("vvvv") 创建了字符串的新实例,但它从未使用过。

return buffer; 中读取 buffer的值后,将调用 finally 块。 对变量 buffer 本身的任何更改都不会返回。

buffer 是 StringBuffer 的情况下你没有更改 buffer 的值而是更改 buffer 的内容,并且该方法的调用者可以看到该内容 。

但是在 buffer 是字符串的情况下,不能执行相同的操作。 字符串不可变。

当 finally 块执行 buffer=buffer.concat("vvvv"); 时它会将新的 String 分配给局部变量 buffer 但是当评估 return buffer; 语句时该方法返回 buffer 引用的原始 String 实例 。

当 finally 块执行 buffer.append("vvvv") 时,它会改变 return buffer 语句返回的相同实例,因此你可以看到从该方法返回的mutated实例。

第一个方法的行为等同于:


StringBuffer buffer = new StringBuffer();


buffer.append("aa");


StringBuffer returned = buffer;


buffer.append("vvvv");//mutates the same instance that will be returned


return returned;



第二种方法的行为等同于:


String buffer = new String();


buffer=buffer.concat("aa");


String returned = buffer;


buffer=buffer.concat("vvvv");//doesn't affect the returned instance


return returned;



...