最近在看堆栈和值传递与引用传递,对这两个概念有了一定的认识,但对待string对象上海存在疑惑,请大家帮忙指正。我觉得str1,经过operate后应该为abcdef,str2经过operate方法后应该为abc,现在str1经过方法后,结果依然为abc。可str1为new出来的对象,传递的应该是引用,操作时,应该修改的是堆内的值,然后让str1指向其值,请问我的理解有何错误,请批评斧正。谢谢。
static void operate(String str) {
str += "def";
}
static void mapAdd(Map<String, String> map) {
map.put("aa", "aa");
}
public static void main(String[] args) {
String str1 = new String("abc");
String str2 = "abc";
operate(str1);
// str1指向了堆中new出的对象abc,像operate传递时,应该传递的是str1的引用
// 在方法中操作后,str1应该指向到操作后的新的对象,也就是abcdef
System.out.println(str1);
operate(str2);
// str2为栈中的对象,传递的就是abc数值,方法操作完后,新的值仅仅是方法中的局部变量
// 值未带出到main方法中来,所以str2还应该是abc
System.out.println(str2);
Map<String, String> map = new HashMap<String, String>();
map.put("bb", "bb");
// 这里没有疑问,mapAdd中传递的map为对象,传递的是引用,操作后map指向了操作后堆中的map值
// 操作后,main方法中map中有两队值。
mapAdd(map);
for (String str : map.keySet()) {
System.out.println(str);
}
}
值传递 引用传递
------解决方案--------------------
当把对象引用str1传递到一个方法后,这个方法可以改变这个对象的属性,并能返回相应的改变,但是这个对象引用指向的这个字符串是永远不会变的。
至于你后面写的那个没有new对象的变量,想改变它的值可以这样写:
class a (int i)
{
i=i+1
}
void main:
int b=3
a A=new a();
A.add(b);sys(b)
------解决方案--------------------
跟堆或池没关系
因为String对象不可修改值
str += "def";
这一句执行之后会在堆中新建一个对象,值是abcdef,再更新str的引用,而str1没有改