public class Test{
public Test(){
StringBuffer a=new StringBuffer("a");
StringBuffer b=new StringBuffer("b");
m(a,b);
System.out.println (a+" "+b);
}
public void m(StringBuffer x,StringBuffer y){
x.append(y);
y=x;
}
public static void main(String args[]){
Test t=new Test();
}
}为什么输出的结果是ab b ,而不是ab ab 呢?这题里的m()中是不是传递的是对象?如果传的是对象是不是就是按引用传递?这样会改变原来数据的值?
public Test(){
StringBuffer a=new StringBuffer("a");
StringBuffer b=new StringBuffer("b");
m(a,b);
System.out.println (a+" "+b);
}
public void m(StringBuffer x,StringBuffer y){
x.append(y);
y=x;
}
public static void main(String args[]){
Test t=new Test();
}
}为什么输出的结果是ab b ,而不是ab ab 呢?这题里的m()中是不是传递的是对象?如果传的是对象是不是就是按引用传递?这样会改变原来数据的值?
然后在方法m里,先x.append(y);对x也就是对象a的引用进行操作,所以直接改变了对象a的值为:ab
再用y=x;这句,把x引用的对象a的引用赋值给y变量,也就是此时y变量重新引用向了a对象,而对b对象没有任何影响.
y = x只是让y指向x指向的内存
而并没有让a改变指向,是吧??学习!!
最后x,y,a指向的是同一个对象
在整个过程中x一直指向a的内存地址,也就是说x是a的一个引用,语句x.append(y);把x的值改为
"ab",由于x是a的一个引用,StringBuffer对象a的值也变为"ab",语句y=x;是使x的内存地址赋给
y,此时y指向了x所指向的内存地址,也就是a的地址,此时的y就和对象b无关了,虽然执行该语句后
y的值变为了"ab",但是由于它和b并无关联,所以对b的值不造成影响,结果就是"ab b"了
public Test(){
String a=new String("a");
String b=new String("b");
m(a,b);
System.out.println (a+" "+b);
}
public void m(String x,String y){
x = x + y;
y = x;
}
public static void main(String args[]){
Test t=new Test();
}
}
这主要还是关于引用方面的东西。
而对于dragon311() 的问题,就是关于String和StringBuffer对象的区别了。
因为“String类是用来表示字符串常量的,用它创建的每个对象都是字符串常量,一经建立便不能修改.”如果是改变的话也应该是重新创建了新的对象后的改变,所以说在使用String时要把他当作一个常量,而使用StringBuffer时,把他当作变量来使用。
也就是最终输出结果为:ab,b
只是传了引用
b还是原来的b,并没有赋值
你在外面定义乐变量,传进函数里的只是一个拷贝,它和外面的变量指向同一个对象,所以你可以调用函数,但改变拷贝,并不会对外面的变量有影响
这是刚进如m(x,y)方法时
这是最开始:
a x b y
↓ ↓ ↓ ↓
__________ __________
| "a" | | "b" |
|__________| |__________|
这是执行了x.append(y)之后
a x b y
↓ ↓ ↓ ↓
__________ __________
| "ab" | | "b" |
|__________| |__________|
这是执行了y=x 一句之后:
a x y b
↓ ↓ ↓ ↓
__________ __________
| "ab" | | "b" |
|__________| |__________|
m(x,y)方法执行完了之后:
a b
↓ ↓
__________ __________
| "ab" | | "b" |
|__________| |__________|此时执行System.out.println (a+" "+b);结果自然是 ab b
这是刚进如m(x,y)方法时
a x b y
↓ ↓ ↓ ↓
__________ __________
| "a" | | "b" |
|__________| |__________|
这是执行了x.append(y)之后
a x b y
↓ ↓ ↓ ↓
__________ __________
| "ab" | | "b" |
|__________| |__________|
这是执行了y=x 一句之后:
a x y b
↓ ↓ ↓ ↓
__________ __________
| "ab" | | "b" |
|__________| |__________|
m(x,y)方法执行完了之后:
a x y b
↓ ↓ ↓ ↓
__________ __________
| "ab" | | "b" |
|__________| |__________|此时执行System.out.println (a+" "+b);结果自然是 ab b
这是因为每一个String对象都是immutable对象;而StringBuffer是mutable的。通过下面的例子可以证明这一点:
public class Test{public static void main(String args[]){ String s1="1";
String s2="2";
String s0=s1;
System.out.println(s0==s1); //s0,s1指向同一个对象
s1=s1+s2;
System.out.println(s0==s1);//s1已经指向了另一个对象 StringBuffer sb1=new StringBuffer("1");
StringBuffer sb2=new StringBuffer("2");
StringBuffer sb0=sb1; System.out.println(sb0==sb1); //sb0,sb1指向同一个对象
sb1.append(sb2);
System.out.println(sb0==sb1); //sb0,sb1仍然指向同一个对象//取消下面语句的注释可以看到s0的值没有改变,而sb0的改变了
// System.out.println("***********\n"+"s0 = "+s0 +"\nsb0 = "+sb0);
}
}简单解释一下:
在对一个immutable对象进行操作的时候,如果你改变了它的值,实际上你并没有改变原来的那个对象,而是得到了一个新的对象;上述例子中s0,s1指向的变化证明了这一点。
而对一个mutable对象进行操作的时候,才是真正改变了操作对象。如sb0,sb1所示。
JAVA是全完全面对象的话语言,在定义对象时,在内存中产生了该类的一个引用。在参数传递过程中所传的就是这个引用值。因此b的引用传给了y,所以b和y引用共一个对象,当y的对象改变时b的对象也改变,所以输出为BA。然而y = x;只是将引用值改变,对象没有改变,所以输出结果没有变化。
x.append(y);
y=x;
}y=x;这句,是将传进来的引用y指向了x,而原来的函数外的实参b的引用没有变,y此时与b已无任何关系了(俗称'野指针')
2引用是地址值但是不透明,java是传值的引用也是值