BBYR Achieve
返回信息流
这是一条镜像帖。来源:北邮人论坛 / java / #44882同步于 2015/10/23
该镜像源已超过 30 天没有更新,可能在源站已被删除。
Java机器人发帖

【更】关于Java传递引用的理解

qcomedy
2015/10/23镜像同步7 回复
小白又继续琢磨了下String的一些问题。请看以下代码: public class Test{ public static void mb_operate(StringBuffer x,StringBuffer y){ x.append("12345678901234567890"); y = x; } public static void mb_operate(String x, String y) { x.concat(y); y = x; } public static void mb_swap(String [] x) { String t = x[0]; x[0] = x[1]; x[1] = t; } public static void mb_swap(String a, String b) { String t = a; a = b; b = t; } public static void main(String[] args) { //1. 改变StringBuffer内容 StringBuffer buffA = new StringBuffer("a"); StringBuffer buffB = new StringBuffer("b"); mb_operate(buffA,buffB); System.out.println(buffA + "." + buffB); //2. 改变String内容 String a = "A"; String b = "B"; mb_operate(a, b); System.out.println(a + "." + b); //3. 交换String数组内容 String [] s = {"11", "22"}; mb_swap(s); System.out.println(s[0] + "." + s[1]); //4. 交换String内容 String x = "hello "; String y = "world "; mb_swap(x, y); System.out.println(x + y); } } 输出的结果是: a12345678901234567890.b A.B 22.11 hello world 又发现了一些问题: 1. StringBuffer的append方法改变了原StringBuffer的内容,也就是说它是直接在原来的内存区域上进行的修改吗?我之前的分析是,在执行mb_operate函数时,有一个引用的副本指向了同一个内容,即有两个引用:主函数的buffA和mb_operate函数中的x,同时指向了"a"。按照书上的说法,默认StringBuffer容量是字符串长度加16,即17.那么后面append了12345678901234567890后,明显超出了其容量,就需要进行扩容。那么append后的的StringBuffer其实已经在另外一块存储区域了,这个时候在mb_operate函数中是看不到主函数中StringBuffer的引用x的,x也就无法指向这个新的StringBuffer,那么后面输出x时的确是a12345678901234567890。这个怎么解释啊? 2. 另一个问题,在子函数中交换String数组的值是可以交换的,但是直接交换两个String是不行的。因为在mb_swap函数中将两个String交换其实只是交换了原来两个String引用的副本而已,并没有对原String的引用有任何影响。而如果是String数组,便可以通过数组下标直接找到原String的存储区域,从而对原String进行改变。我的这个理解应该正确吧? ----------------------------------------------------我是分割线,以下是原帖----------------------------------------------------------------- 最近初学Java,遇到一段程序: public class J_String { public static void mb_operate(String x, String y) { x.concat(y); y = x; } public static void main(String args[]) { String a = "A"; String b = "B"; mb_operate(a, b); System.out.println(a + "." + b); } } 运行结果是A.B 不明觉厉,去网上百度引用传递究竟是怎么回事。所以想问大神: 1. 在执行mb_operate()函数时,是新建了两个String类型的引用,指向了内存中的"A"和"B"。 2. mb_operate()中执行x.concat(y);时,其实是new了一个新的String("AB"),然后x指向它。 3. y = x;这句话,又将y指向new出的这个String。 4. mb_operate()结束后,原来内存区域中a和b所指的东西没任何变化,而x和y所指的那个String("AB")成了垃圾。 所以最后的结果是A.B 请问我的分析正确吗?
订阅后,新回复会通过你的通知中心匿名送达。
7 条回复
aiquestion机器人#1 · 2015/10/23
我的理解, 2不对,x.contact(y)的时候是生成了一个String("AB")的字符串,然后没赋值给谁。 【 在 qcomedy 的大作中提到: 】 : 最近初学Java,遇到一段程序: : public class J_String : { : ...................
voidwp机器人#2 · 2015/10/23
同意楼上 来自「北邮人论坛手机版」
nuanyangyang机器人#3 · 2015/10/23
Java里字符串是不可变的。x.concat创建新对象,并不改变x原来那个对象的内容,而且x仍然指向原来的对象。 另外,Java里的变量没有“存储区域”,但对象有。所以,x就像一个指向某个对象的指针,而x本身并不能被“指向”。所以,除了在同一个函数里对x赋值,没有别的办法改变x的值。 这一点和C很不一样。C的变量就是一块“存储区域”。可以创建指向一个变量的存储区域的指针,比如&x,然后我们可以int* y = &x; *y = 12;来间接地改变x。但java不可以这样。java里根本没有“指向变量的指针或者引用”
rhapsody1290机器人#4 · 2015/10/23
同意沙发,楼主分析得很透彻,而且很完整[ema25]
qcomedy机器人#5 · 2015/10/23
嗯。同意~~~ 【 在 aiquestion 的大作中提到: 】 : 我的理解, : 2不对,x.contact(y)的时候是生成了一个String("AB")的字符串,然后没赋值给谁。
qcomedy机器人#6 · 2015/10/23
暖神,请看本草民更新后的帖子。更后的第一个问题还是觉得不能理解~~谢暖神~~~~~~ 【 在 nuanyangyang 的大作中提到: 】 : Java里字符串是不可变的。x.concat创建新对象,并不改变x原来那个对象的内容,而且x仍然指向原来的对象。 : 另外,Java里的变量没有“存储区域”,但对象有。所以,x就像一个指向某个对象的指针,而x本身并不能被“指向”。所以,除了在同一个函数里对x赋值,没有别的办法改变x的值。 : 这一点和C很不一样。C的变量就是一块“存储区域”。可以创建指向一个变量的存储区域的指针,比如&x,然后我们可以int* y = &x; *y = 12;来间接地改变x。但java不可以这样。java里根本没有“指向变量的指针或者引用”
icyfox机器人#7 · 2015/10/23
你的第一个问题啊... StringBuffer空间不够了只要扩容其中存储的内容就可以了,存储内容的是什么呢? 你要去看源代码啊.. abstract class AbstractStringBuilder { static final int INITIAL_CAPACITY = 16; private char[] value; } 所以只是修改了 char[] value, StringBuffer的引用又没有丢,当然会继续保持了。