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

请教一个字符串和数组的值和引用的问题
请先看第一段代码
String []name3 = new String[]{"james","jerry"};
String []name4 = new String[2];
name4 = name3;
name4[0] = "lucy";
for(int i=0;i<name3.length;i++){
System.out.print(name3[i]+"\t");
}
输出结果 lucy jerry 我修改第二个数组的首位元素第一个数组的首位元素也跟着改变了

第二段代码
String name1 = new String("james");
String name2 = new String();
name2 = name1;
name2 = "lucy";
System.out.println(name1);
输出结果 james

我的问题是同样是引用数据类型为什么name3[0]的值就跟着变了,而name1的值没变呢?

------解决方案--------------------
首先name1 name2利用new的时候在堆区创建两个String对象,然后将引用赋值给name1 name2,然后执行name2=name1是将name2的引用的指向跟name1相同,这时候打印name2 name1的值都会是空字符串
接下来name2="lucy",因为String是不可变类,实际上堆区的空字符串对象没有改变,JVM在堆区重新创建的一个String对象内容是lucy并让name2的获得其引用,而name1的引用还是指向原来的内存地址(空字符串)
因此name2="lucy"因为重新开了一个String对象,name2值变化,而name1的引用对象没有销毁,还是原来的空值
------解决方案--------------------
对字符串进行操作的时候是针对对象的引用,并不是对象的本身
------解决方案--------------------
数组那个给你解释下,name3 name4都是数组名,理解为JVM解释执行数组对象的引用,两个数组长度一致,执行name4=name3之后两个数组的内容就会完全一样,因为你遍历数组比如检索name3[1]还是通过name3这个引用找name2[1],也是说说执行name4=name3之后 name3 name4里面元素的数组引用是朝向了同样的地址
并且因为是数组地址的引用,两者元素的指向会保持同步,不会像String类型一样会指向不同地方

探讨
里面的数组每个元素也是String类型性的,这有什么区别么?

------解决方案--------------------
name4 = name3
不是将name3里的元素考到name4中
而是将name4这个引用也指向name3指向的对象数组
你如果做
name4 = name3
上面一行的new String[2]可以省略
------解决方案--------------------
楼主 :第二个你应该是明白的吧,就说第一个吧。
首先 name3 指向----->name3[0]与name3[1]又是一个引用,而 name4指向--------->name4[0],name4[1]两个引用。
 通过赋值后 ,name4----->name3[0]与name3[1],name4就不能指向>name4[0],name4[1]这连个两个引用了。
因此name4[0]与name3[1]实际就是一个引用了。name4[0]与name3[0] 实际上是同一个内存单元。

而在第二个中name1 与name2 的引用占用的两个不同的内存地址。
name2中 每创建一个一个对象 或者赋值一个引用 他的值都会变化 。而name1中一直没得改变。
------解决方案--------------------
第一个两个引用指向的是同一个对象,对对象的任何修改都会引起两个引用引用的对象值的变化。

第二个问题,你是吧引用指向了另外一个对象了。
------解决方案--------------------
建议你看一下值传递那一块的描述

name4 = name3;//这里传递的是引用变量的地址值,也就是二个引用变量指向了同一个String数组对象



name2 = "lucy";//name2又重新引用了"Lucky"对象了 而name1没有改变