日期:2014-05-20  浏览次数:20723 次

求大侠帮忙解答一下关于List<String> 的问题
本帖最后由 zjxbr 于 2013-04-28 15:38:31 编辑
新人第一次发帖,不要看结贴率谢谢。。。。钱少就少给点就20呵呵~~

public static void t2() throws InterruptedException{
List<String> aL = new ArrayList<String>();
String a = new String("www");

aL.add(a);

for(String tmp : aL){
tmp = "xxx";
}

CommonPrint.print(aL);
}


上面这段代码声明了一个List,然后把"a"加入到该list,
意图是遍历List,修改里面的元素变为"xxx"。
但是运行结果还是"www"

根据我的理解,
String a = new String("www"); 在栈里新建了一个a,指向了堆内新开辟的"www",因为是new的。
然后把栈里的a这个地址加入到List中。
然后遍历list,取得a,再新开辟一个"xxx"赋值给a。
这样list保存的值应该只有一个,是"xxx"而不是"www",但是结果刚好相反,值没有变!
我觉得在堆里新建的"www"已经没有栈里的引用指向他了,应该快被垃圾回收期回收了,但是好像不是这样的。
哪位帮忙告诉一下我哪里概念错了。

还有就是如果把String 换成一个自定义的对象,按照这个方法是可以改变对象属性的,不知道为什么String就比不行,即使用了new String();
Java String

------解决方案--------------------
你有一个碗
你有一个苹果,上面插了根筷子
你把苹果放到碗里。
你把筷子插到另一个梨子上
然后你问为什么我碗里的不是梨子而是苹果?
------解决方案--------------------
23456789101112 

public static void t2() throws InterruptedException{
    List<String> aL = new ArrayList<String>();
    String a = new String("www");
    aL.add(a);
    for(String tmp : aL){
        tmp = "xxx";   
     }             
CommonPrint.print(aL);} 

aL里面放的是"www"
你把"xxx"的值赋给了tmp
然后你打印出aL的值
当然是www了  因为你的tmp和aL没有发生任何关系
------解决方案--------------------
再新开辟一个"xxx"赋值给a
这里理解错了。

指向xxx对象的是tmp,不是a

a指向的还是原来的www对象,没变
------解决方案--------------------
for(String tmp : aL){
        tmp = "xxx";   
}    
for(int i = 0; i < aL.size(); i++){
      String tmp = aL.get(i);
      tmp = "xxx";
}

understand????
上面连个遍历是等价的
------解决方案--------------------

//同意上面的
for (int i = 0; i < aL.size(); i++) {
String tmp = aL.get(i);
tmp = "xxx";
aL.remove(i);
aL.add(i, tmp);
}
//这是楼主想要的意思吧
------解决方案--------------------
首先,说下你的流程:
1,分别new了一个集合aL,一个String  a="www";
2,将a的引用给了aL;
3,for循环遍历aL各元素,用tmp接受,这里只有一个,for循环内tmp得到的是字符串a的引用(类似方法中的形参),然后你给将String常量池中的"xxx"的引用给了tmp;
4,打印集合aL中的元素;
你根本就没有改变a,集合中的唯一元素就是a,所以不会变为"xxx";
你说的<<修改里面的元素变为"xxx">>理解有问题,遍历只是取引用,用变量接收,此时你变量如果用如<<tmp="xxx">>的形式做改变,只是又接收了其他引用,指向变了,此行之前tmp==a,之后tmp!=a(a的内容是"www"而tmp的内容是"xxx")