class Test{
public static void main(String[] args) {
String s1 = new String("java");
String s2 = new String("hello");
method_1(s1,s2);
System.out.println(s1+"...."+s2); //java....hello
StringBuilder s11 = new StringBuilder("java");
StringBuilder s22 = new StringBuilder("hello");
method_2(s11,s22);
System.out.println(s11+"-----"+s22);
}
public static void method_1(String s1,String s2){
s1=s1.replace('a','k'); s1 = s2; }
public static void method_2(StringBuilder s1,StringBuilder s2){
s1.append(s2); s1 = s2; }
}
public static void main(String[] args) {
String s1 = new String("java");
String s2 = new String("hello");
method_1(s1,s2);
System.out.println(s1+"...."+s2); //java....hello
StringBuilder s11 = new StringBuilder("java");
StringBuilder s22 = new StringBuilder("hello");
method_2(s11,s22);
System.out.println(s11+"-----"+s22);
}
public static void method_1(String s1,String s2){
s1=s1.replace('a','k'); s1 = s2; }
public static void method_2(StringBuilder s1,StringBuilder s2){
s1.append(s2); s1 = s2; }
}
我怎么误导了,应该不会啊,我虽没用运行,但是觉得理论上应该是的啊。
method1调用后,应该不变,这个应该没有异议。
method2调用后,s1.append(s2);这一句肯定会改变s1的值,但是s1 = s2;并不会改变s2,所以打印出来应该是java hello hello,hello会被重复一次。
我想应该是这样。
然后方法执行完了之后,方法内的s1没了,可是外面的s1还是指向的0001。而0001里面还是原来的字符串。方法2中,接收的也是两个引用,拿s1举例,s1.append(s2);会直接对0001这个地址进行操作,这样的话0001里面的字符串就变了,第二行s1=s2,这个局部的s1的引用就指向了s2的引用,比如是0003,然后方法返回,局部的s1和s2都销毁了,方法外输出的时候,0001里的对象已经变了
s1=s1.replace('a','k');
这个操作怎么没有效果?
java....hello
javahello-----hello
这个操作其实是有效果的,在method_1()方法内你用System.out.println()语句将s1和s2打印出来可以验证s1和s2被"暂时"改变了,只是在调用此方法之后,该方法占用的内存会被释放,也就是说,传参数的时候是传的一份原变量s1和s2的拷贝,所以对原变量无影响,楼主如果有c语言的基础应该这些能够理解
照着这么说s1=s1.replace('a','k');这一句应该起作用吧
s1指向的对象已经改变了,把a变成k
可结果却没有哦
但是StringBuilder就不一样了,是可变类型,可以直接对它所指向的内存空间修改内容。
//接下来method_1(s1,s2);这个方法调用的意思就是新配了一把钥匙s1,这个钥匙也能开上面那个箱子1,这是引用传递,但由于string是不变对象,是值传递,所以method_1(s1,s2)(引用传递就理解为新配一把钥匙,值传递就理解为把箱子里的东西复制一份放到另外的箱子里面)
//传给参数s1的不是钥匙,而是苹果。意思就是有了另外一个箱子2,钥匙是参数s1,箱子2里也有个苹果。而method_1里面的s1=s1.replace('a','k');改变的是箱子2里的苹果。箱子1里面的
//东西根本没变,而method_1(s1,s2);调用的作用域在main函数里,main函数里的s1是指第一个箱子,所以第一个输出java....hello。这样就不难理解method_2了。method_2(s11,s22);
//这个方法调用是指给箱子3 s11配了把钥匙s1,给箱子4 s22配了把钥匙s2(因为stringbuffer是引用传递,不是string那样的值传递),method_2函数里的s1.append(s2);这句话表明用s1
//这把钥匙打开箱子3,给他加了个梨。现在箱子3里就有梨和苹果了(javahello),s1=s2这句话就是把s1这把钥匙打磨下能打开箱子4了,就不能打开箱子3了。但是注意,箱子3的原配钥匙s11并
//没有变化,还是打开箱子3,现在变的是箱子3里面的东西。method_2(s11,s22);这个方法调用的作用域在main方法里,所以s11打开箱子3(javahello),s22打开箱子4(hello)输出结果是
//javahello----hello
1)对于int、float等八种基本类型的对象,传递的是他本身的内容值(箱子里面的苹果)
2)对于String、定义的类等其他类型的对象,传递的是他在内存中的地址值(箱子的钥匙)
建议看一看这位仁兄的论述和代码http://www.cnblogs.com/clara/archive/2011/09/17/2179493.html
如果参数类型是原始类型,那么传过来的就是这个参数的一个副本,也就是这个原始参数的值,这个跟之前所谈的传值是一样的。如果在函数中改变了副本的 值不会改变原始的值.
如果参数类型是引用类型,那么传过来的就是这个引用参数的副本,这个副本存放的是参数的地址。如果在函数中没有改变这个副本的地址,而是改变了地址中的 值,那么在函数内的改变会影响到传入的参数。如果在函数中改变了副本的地址,如new一个,那么副本就指向了一个新的地址,此时传入的参数还是指向原来的 地址,所以不会改变参数的值。
这个说法比较靠谱一点。但是没有说完全。比如 s1.append(s2);得到了javahello。
那s1 = s2 这个为什么后面没有变成hello。
class Test{public static void main(String[] args) {
String s1 = new String("java");
String s2 = new String("hello");
method_1(s1,s2);
System.out.println(s1+"...."+s2); //java....helloStringBuilder s11 = new StringBuilder("java");
StringBuilder s22 = new StringBuilder("hello");
method_2(s11,s22);
System.out.println(s11+"-----"+s22);
}
public static void method_1(String s1,String s2){
s1.replace('a','k');s1 = s2;}
public static void method_2(StringBuilder s1,StringBuilder s2){
s1.append(s2);s1 = s2;}
} 结果是一样的,
而且s1.replace('a','k')指向的是同一个内存区,只是replace()方法没有改变结果。越来越糊涂了,请解答一下,谢谢!
javahello-----hello
String类的对象不可以对内容进行动态的操作,比如删减增加字符
method——1中s1 = S2 只是对地质进行了赋值而没有对字符串内容进行改变所以不能改变内容
而StringBuilder是一个可变的字符序列类 ,和StringBuffer都是对字符串进行动态操作的类所以可以改变内容
StringBuilder不是mutable类型,所以做为参数传入方法时是传引用(java的引用概念和C++不太一样),所以第二个方法会改变传入的值
s1 = s2 这个和s1.append(s2)不一样,s1 = s2;是引用传递,方法执行完,效果就没了。我在图中有画的。