黑马程序员——JAVA——参数传递机制
来源:互联网 发布:网络说唱歌曲大连站 编辑:程序博客网 时间:2024/06/05 23:53
------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------
昨天在论坛上看到个人问了个这样的问题。
public class Test{ public static void main(String[] args) { String string = "Hello"; test(string); System.out.println(string); } public static void test(String str) { str = "World"; }}为什么输出的是Hello而不是World?
说到这个问题就不得不提到java的参数传递机制。
一般来说参数传递的方式有两种:值传递和引用传递。
但是在JAVA中不存在引用传递,JAVA编程语言只有值传递。
JAVA中的参数传递,不论是值传递还是引用传递,其本质上传递的都是副本(其实就是值,我看有的帖子上称为副本,可能是值与值传递容易弄混,这里也称为副本)。
——当传递的参数类型是基本数据类型时,那么传过来的就是这个参数的一个副本,也就是原始参数的值。如果在函数中,副本中的值进行了变动,原始参数的值并不会随着副本的值而改动。
——当传递的参数类型是引用数据类型时,那么传过来的也是这个参数的一个副本,只不过这个副本是原始参数的地址的值。如果在函数中,副本中的地址没有进行变动,而是改变了地址中的某个值,那么函数内的变动会影响原始参数。如果在函数中,副本中的地址发生了改变,比如new了个新的对象,那么副本就指向了这个新的对象,而原始参数不会因为函数内的变动而变动。
下面分别从两种传递方式的内存模型讨论下java中的参数传递。
基本数据类型:
public class Demo1{public static void main(String[] args) { int num = 3; System.out.println("调用add方法前num=" + num); test(num); System.out.println("调用add方法后num=" + num);}public static void test(int num) {num = 5;}}运行结果: 调用add方法前num=3
调用add方法后num=3
内存:当执行int num = 3;程序在栈内存中开辟了一个新内存(如地址为0x13001),并存放了3这个数值。当执行到test方法时,程序又开辟了一个新的内存(如地址为0x13002),并将num的值3传了进来,此时num的值是3。当执行到num=5;后,0x13002地址中的值变成了5。
也就是说地址0x13002是函数中副本的地址,无论副本怎么改变,原始参数都不会发生变化。
引用数据类型:
public class Demo1{public static void main(String[] args) { String[] array = new String[] {"Hello"}; System.out.println("调用reset方法前array中的第0个元素的值是:" + array[0]); reset(array); System.out.println("调用reset方法后array中的第0个元素的值是:" + array[0]); } public static void reset(String[] param) { param[0] = "World"; }}运行结果: 调用reset方法前array中的第0个元素的值是:Hello
调用reset方法后array中的第0个元素的值是:World
内存:当程序执行到String[] array = new String[] {"Hello"};时,程序在堆内存中new了一个新的对象地址为0x13001,并把这个地址给了栈内存中开辟了一个空间的array。当春训运行到reset方法时,程序如基本数据类型那样同样在内存中开辟了一个新空间存放param,并把array中存放的地址0x13001给了param,也就是说此时param也指向了0x13001这个地址。之后执行赋值语句param[0] = "World";,是对0x13001这二个地址中的值进行修改。所以原始参数中0x13001的值也进行了变动。
也就是说地址0x13001是作为一个值被传递进函数的,只要这个值没有改变(如不new新对象),通过这个地址对参数进行修改,原始参数的值也会改变的。
总结:无论是基本数据类型还是引用数据类型,进行的都是值传递,只不过值的形式不同一个传的是值,一个传的是地址。
最后再来看看一开始的问题。
test方法中传递的是一个字符串的地址,按理来说只要函数中不new新字符串,原始字符串中的值就会随着函数中的变动进行变化。
然而函数中的str = "World";相当于new了个新的字符串(str=new String("World");)。所以函数中的改动并没有影响原始参数。
- 黑马程序员——JAVA——参数传递机制
- 黑马程序员 函数调用 —参数传递
- 黑马程序员——java基础——方法、数组、二维数组、参数传递
- 黑马程序员——Java中的一个关于参数传递的小问题
- 黑马程序员——Java 反射机制
- 黑马程序员——-Java反射机制-
- 黑马程序员——java反射机制
- 黑马程序员——Java反射机制
- 黑马程序员——Java异常机制
- 黑马程序员—Java中的反射机制
- 黑马程序员—关于java反射机制
- 方法的参数传递机制——值传递机制
- 黑马程序员—反射机制
- 黑马程序员—反射机制
- java基础——方法参数的值传递机制
- Java基础——方法的参数传递机制
- 黑马程序员--Java中参数传递问题
- 黑马程序员——Java高新技术——反射机制
- eclipse 打包jar及提交spark执行步骤
- Varnish+Nginx搭建缓存服务器
- imageload如何更改文件名
- MySQL优化之——修改默认存储引擎
- 第十三章,隐式intent小demo(Android)
- 黑马程序员——JAVA——参数传递机制
- oracle decode函数
- ormlite
- 火绒 完美卸载 流氓软件的检测与防护方法动画演示
- SAT考试阅读练习题5
- iOS TableView实现QQ好友列表(三)
- 两个基于C++-Qt的开源WEB框架
- php中explode与split的区别介绍
- Nginx+Lua开发