返回信息流小白又继续琢磨了下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
请问我的分析正确吗?
这是一条镜像帖。来源:北邮人论坛 / java / #44882同步于 2015/10/23
该镜像源已超过 30 天没有更新,可能在源站已被删除。
Java机器人发帖
【更】关于Java传递引用的理解
qcomedy
2015/10/23镜像同步7 回复
订阅后,新回复会通过你的通知中心匿名送达。
7 条回复
我的理解,
2不对,x.contact(y)的时候是生成了一个String("AB")的字符串,然后没赋值给谁。
【 在 qcomedy 的大作中提到: 】
: 最近初学Java,遇到一段程序:
: public class J_String
: {
: ...................
Java里字符串是不可变的。x.concat创建新对象,并不改变x原来那个对象的内容,而且x仍然指向原来的对象。
另外,Java里的变量没有“存储区域”,但对象有。所以,x就像一个指向某个对象的指针,而x本身并不能被“指向”。所以,除了在同一个函数里对x赋值,没有别的办法改变x的值。
这一点和C很不一样。C的变量就是一块“存储区域”。可以创建指向一个变量的存储区域的指针,比如&x,然后我们可以int* y = &x; *y = 12;来间接地改变x。但java不可以这样。java里根本没有“指向变量的指针或者引用”
嗯。同意~~~
【 在 aiquestion 的大作中提到: 】
: 我的理解,
: 2不对,x.contact(y)的时候是生成了一个String("AB")的字符串,然后没赋值给谁。
暖神,请看本草民更新后的帖子。更后的第一个问题还是觉得不能理解~~谢暖神~~~~~~
【 在 nuanyangyang 的大作中提到: 】
: Java里字符串是不可变的。x.concat创建新对象,并不改变x原来那个对象的内容,而且x仍然指向原来的对象。
: 另外,Java里的变量没有“存储区域”,但对象有。所以,x就像一个指向某个对象的指针,而x本身并不能被“指向”。所以,除了在同一个函数里对x赋值,没有别的办法改变x的值。
: 这一点和C很不一样。C的变量就是一块“存储区域”。可以创建指向一个变量的存储区域的指针,比如&x,然后我们可以int* y = &x; *y = 12;来间接地改变x。但java不可以这样。java里根本没有“指向变量的指针或者引用”
你的第一个问题啊...
StringBuffer空间不够了只要扩容其中存储的内容就可以了,存储内容的是什么呢? 你要去看源代码啊..
abstract class AbstractStringBuilder {
static final int INITIAL_CAPACITY = 16;
private char[] value;
}
所以只是修改了 char[] value, StringBuffer的引用又没有丢,当然会继续保持了。