String的按值传递,java传参都是传值
来源:互联网 发布:mac python idle 下载 编辑:程序博客网 时间:2024/06/07 09:50
转载
http://www.cnblogs.com/woshimrf/p/5263018.html
http://www.cnblogs.com/chenpi/archive/2016/05/15/5494980.html
java中对象作为参数传递给一个方法,到底是值传递,还是引用传递?
String和int参数传递是按值传递还是引用传递?
一道面试题目,String的传递:
public String change(String s){ s = "222"; return s; }public static void main(Stirng[] args){ String s = "111"; change(s); sout(s);}输出:111
ava 编程语言只有值传递参数。当一个对象实例作为一个参数被传递到方法中时,参数的值就是该对象的引用一个副本。指向同一个对象,对象的内容可以在被调用的方法中改变,但对象的引用(不是引用的副本)是永远不会改变的。
测试
public String change(String s, int i, StringBuffer sb, Person p){ s="123"; i=3; sb.append("woshi"); p.setAge(100); sb = new StringBuffer("sbsb"); p = new Person("bb",44); return s; } @Test public void testChange(){ StringBuffer sb = new StringBuffer("buff"); String s = "aaa"; int i = 1; Person p = new Person("aa",12); i=2; change(s,i,sb,p);// s="222"; System.out.println(s); System.out.println(i); System.out.println(sb.toString()); System.out.println(p); }输出aaa2buffwoshiPerson{id=0, name='aa', age=100, Country=null, hashcode=638783031}
分析
String
String s = "aaa";
这里,jvm创建一个变量引用s,在堆中创建一个对象aaa,将aaa放进常量池。s指向aaa。
然后就到了change方法里。这里这样理解:将s引用的一个拷贝传给方法change。这样change有一个变量s,这个s也是指向aaa的。那么我们来通过debug来看后来发生了什么。
1.s指向aaa的时候:
2.s运行到change方法里的时候
然后看s再次赋值的时候:
然后我们运行结束change方法后到主方法里:
到这里s就结束了。那么如果我们按照传递的是s这个变量的引用,即String s=”aaa”中这个s本身,那么,s这个本身是个变量,s指向aaa,在方法change里s又指向了123,回到主方法后s变量的指向被改变了?错!显然s仍旧是aaa,那么只能这样理解:s传递到方法里的时候,复制了s指向的地址给change,change里的s是另一个s,s指向aaa(@718),然后在change中s又指向了123(@731),由于String是不可变类(final and Immutable),这里只是把副本s的指向修改成731,原地址718里的对象没有发生改变因为String不可变。那么,回到主方法的时候,s变量本身没有任何改变,s仍旧指向地址718,718的内容是aaa。所以最终打印aaa。
StringBuffer
int是基本类型,所以int只是将值复制一份给别的方法用,这个大家都知道,就不去测试了。现在看StringBuffer发生的改变。
1.初始化:
2.到change方法中:
3.发生append
4.指向新对象
这里就要说一下了,副本指向了新对象。就好比,施瓦星格的克隆人找了另一个女的当老婆,而真正的施瓦星格老婆没有变。
5.回到主方法:
到这里,StringBuffer就结束了。我们必须知道,虽然我们没有去研究源码是怎样实现的,change方法得到是一个sb的副本,只不过这个副本指向708,在change里对708的对象追加,708的对象就真的改变了。然后又把sb副本指向新地址737。这只是把副本指向的地址修改了,如果你在这里打印sb.toString(),打印的就是737里的内容。当跳出change,回到主方法的时候,原sb仍旧还是指向708的,最终就是打印708的结果。和String不同的是,StringBuffer的结果发生了变量,因为StringBuffer是可变的,可以append。而String是不可变的,在change中s=123就是发生两个行为,一个是查找常量池中是否有123,如果没有就在堆中创建123,一个是将s指向123.也就是说这时候是创建了一个新的String对象,而不是把原来的String对象s内容修改。这样,回到主方法的时候,s仍旧是aaa。
people
1.初始化
2.p传递到change里的时候
3.p副本设置age
4.p副本重新赋值
这里仍旧要说一下,p副本修改了自己指向,并不影响主方法里的p的指向。主方法里的p的指向没有发生变化,依旧应该还是720.
5.回到主方法
总结:
值作为参数我就不讲了,对象作为参数,其实参数的值是对象的引用,拷贝的是引用值。String作为参数拷贝的也是引用值,不过在给String赋值的时候是重新创建一个对象。
如图所示
public static void change(String x) { x = "cd"; } public static void main(String[] args) { String x = new String("ab"); change(x); System.out.println(x); }
- String的按值传递,java传参都是传值
- String的按值传递,java传参都是传值
- String的按值传递,java传参都是传值
- String的按值传递,java传参都是传值
- String的按值传递,java传参都是传值
- String的按值传递,java传参都是传值!!!
- java所有类型的参数传递都是“值传递”
- 理解JAVA里的所有参数传递都是值传递
- java都是值传递 测试
- 在Java里面参数传递都是按值传递
- java方法调用都是值传递的理解
- 我的理解:Java 中方法的参数全部都是按“值”传递的
- java中的传递参数其实都是值传递(引用就是拷贝对象的一个地址)
- java String 的值传递问题
- JS函数参数都是按值传递的!
- ES5中的函数都是按值传递的
- 关于JAVA的值传递和引用传递&String
- Java的方法的参数传递,值传递和引用传递还有String字符串传递
- android获取天气API
- A
- Java-求斐波那契数列前20项的值并输出
- 最重要的是@timestamp,用来标记事件的发生时间。
- Android学习(十四)五布局之绝对布局AbsoluteLayout
- String的按值传递,java传参都是传值
- Programming Assignment 1: Percolation代码
- 使用mysql查询数据表中某个字段包含某个数值
- 谷歌开源机器学习可视化工具 Facets:从全新角度观察数据
- 从单一WAR到多活, 记述一个创业公司的架构演变
- Java-求出所有的水仙花数(各位数字立方之和等于数本身的三位整数)并输出。
- CSU 1809 Parenthesis (线段树)
- intellij idea关闭vim模式
- Linux中fork()函数