JAVA 是参数传递 不是引用传递 例子
2017-03-15 10:26
351 查看
public class JunitTest {
public static void process(String str)
{
str="A";
}
public static void process(StringBuffer sb)
{
sb=new StringBuffer();
sb.append("A");
}
public static void process(String str,StringBuffer sb)
{
str=new String("A");
sb.append("A");
}
public static void main(String args[]) {
String str="a";
StringBuffer sb=new StringBuffer("a");
process(str);
System.out.println(str);
process(sb);
System.out.println(sb);
process(str,sb);
System.out.println(str);
System.out.println(sb);
}
}
#考虑下会打印的值
问题:String,StringBuffer不都是引用类型吗,为什么代码运行的结果是a a a aA(没有变化)?
------解决方案--------------------
如果你认为引用类型在函数内修改值就一定能反映到外部,那只能说明你还没真正理解引用
第一个process,局部变量赋值,这只改变了局部变量的指向,并不能改变原来指向的String的内容
第二个process,同样的问题,给局部变量赋值,sb = new StringBuffer();以后sb就不是外部那个StringBuffer了,所以随便你怎么修改也不会反映到外部
第三个process,str = new String("A");和前面两个是一样的问题,而sb.append("A");是有效的,所以你看到最后输出了aA
------解决方案--------------------
方法中的参数时局部变量来的,拿最后一个来说吧,方法public static void process(String str, StringBuffer sb) 中参数str和sb都是局部变量,调用process(str,sb),是让局部变量跟传入的参数指向同一个对象,str = new String("A");只是将局部变量str指向另一个对象引用,跟外部的str没有关系,所以str仍为a,而sb.append("A");是将局部变量sb指向的对象追加"A",而由于局部变量指向的对象跟外部的sb指向同一个对象,所以外部的sb也就变成aA了。
------解决方案--------------------
画个图形象一点,以第二个process过程为例,首先sb指向一个StringBuffer对象
然后调用process(sb),因为Java只有按值传递参数(为了区分这里将参数名改为sb2),所以sb的值传给sb2,也就是现在sb2也指向那个StringBuffer对象
然后你sb2 = new StringBuffer(),实际上就是新创建一个StringBuffer对象,然后让sb2指向他,所以在这之后无论你怎么修改,也是修改新创建的StringBuffer对象,和原来的对象没有一丝关系
------解决方案--------------------
关于这个方法
1、StringBuffer sb=new StringBuffer("a");
2、process(sb);
3、public static void process(StringBuffer sb) {
4、sb = new StringBuffer();
5、sb.append("A");
}
我举个例子吧。
一:第1行,创建一个实例,假设此时sb变量的值为0x000001
二:然后执行到第3行,又来了个sb,注意这和前面的sb不是同一个东西,只是大家的值都为0x000001而已,现在假设后面的sb为sb(1)咯,注意了,方法process里面的sb全是sb(1)
三:执行到第四行,sb1的地址突然改变了,假设变为0x000002了
四:执行到第五行,这里当然是地址0x000002的对象改变啦
五,方法执行完毕,结果0x000001地址的对象并没有改变,所以前一个sb指向的对象并没有改变!
public static void process(String str)
{
str="A";
}
public static void process(StringBuffer sb)
{
sb=new StringBuffer();
sb.append("A");
}
public static void process(String str,StringBuffer sb)
{
str=new String("A");
sb.append("A");
}
public static void main(String args[]) {
String str="a";
StringBuffer sb=new StringBuffer("a");
process(str);
System.out.println(str);
process(sb);
System.out.println(sb);
process(str,sb);
System.out.println(str);
System.out.println(sb);
}
}
#考虑下会打印的值
问题:String,StringBuffer不都是引用类型吗,为什么代码运行的结果是a a a aA(没有变化)?
------解决方案--------------------
如果你认为引用类型在函数内修改值就一定能反映到外部,那只能说明你还没真正理解引用
第一个process,局部变量赋值,这只改变了局部变量的指向,并不能改变原来指向的String的内容
第二个process,同样的问题,给局部变量赋值,sb = new StringBuffer();以后sb就不是外部那个StringBuffer了,所以随便你怎么修改也不会反映到外部
第三个process,str = new String("A");和前面两个是一样的问题,而sb.append("A");是有效的,所以你看到最后输出了aA
------解决方案--------------------
方法中的参数时局部变量来的,拿最后一个来说吧,方法public static void process(String str, StringBuffer sb) 中参数str和sb都是局部变量,调用process(str,sb),是让局部变量跟传入的参数指向同一个对象,str = new String("A");只是将局部变量str指向另一个对象引用,跟外部的str没有关系,所以str仍为a,而sb.append("A");是将局部变量sb指向的对象追加"A",而由于局部变量指向的对象跟外部的sb指向同一个对象,所以外部的sb也就变成aA了。
------解决方案--------------------
画个图形象一点,以第二个process过程为例,首先sb指向一个StringBuffer对象
然后调用process(sb),因为Java只有按值传递参数(为了区分这里将参数名改为sb2),所以sb的值传给sb2,也就是现在sb2也指向那个StringBuffer对象
然后你sb2 = new StringBuffer(),实际上就是新创建一个StringBuffer对象,然后让sb2指向他,所以在这之后无论你怎么修改,也是修改新创建的StringBuffer对象,和原来的对象没有一丝关系
------解决方案--------------------
关于这个方法
1、StringBuffer sb=new StringBuffer("a");
2、process(sb);
3、public static void process(StringBuffer sb) {
4、sb = new StringBuffer();
5、sb.append("A");
}
我举个例子吧。
一:第1行,创建一个实例,假设此时sb变量的值为0x000001
二:然后执行到第3行,又来了个sb,注意这和前面的sb不是同一个东西,只是大家的值都为0x000001而已,现在假设后面的sb为sb(1)咯,注意了,方法process里面的sb全是sb(1)
三:执行到第四行,sb1的地址突然改变了,假设变为0x000002了
四:执行到第五行,这里当然是地址0x000002的对象改变啦
五,方法执行完毕,结果0x000001地址的对象并没有改变,所以前一个sb指向的对象并没有改变!
相关文章推荐
- Java中方法调用参数传递的方式是传值,尽管传的是引用的值而不是对象的值。(Does Java pass by reference or pass by value?)
- JAVA中方法的参数是按值传递的,有个例子很经典
- java传递是引用的拷贝,既不是引用本身,更不是对象
- java 传递参数 “引用是一种数据类型”,“参数是引用的一个拷贝”
- 一个简单的例子,证明JAVA参数是通过值传递
- java中的参数传递与引用
- java传递是引用的拷贝,既不是引用本身,更不是对象
- Java中的原生数据类型和引用类型的参数传递
- Java软件低级错误(九 ):Java参数传递:传值还是传引用?
- java中的参数传递——值传递、引用传递
- Java中的参数传递---按值?按引用?
- 在Java中方法参数的传递,对象是传递引用
- Java中的参数传递方式到底是引用传递还是值传递?
- C++的引用传递、指针传递参数在java中的相应处理方法
- java参数传递究竟是按值呢,还是引用?
- Java函数参数的值传递和引用传递
- 在Java中方法参数的传递,对象是传递引用
- Java方法强制传递引用参数(做为返回值),改变被传递参数值。
- Java中函数参数的传递是值传递还是引用传递
- java中关于参数传递问题的解释(传值与传引用的若干问题的解释)