Java编程基础之方法调用时的参数传递
在Java代码中调用函数时传递参数有两种说法,一种是传值,一种是传引用。如果是用Java的基本类型(int,boolean等)做参数认为是传值,如果是对象类型认为是传引用。下面来剖析一下传对象引用这种场景。
看下面这道Java基础题:
1 package com.elon.integertest; 2 3 public class StartupIntegerTest { 4 public static void main(String[] args) { 5 Integer i = new Integer(1); 6 System.out.println("a: i=" + i); 7 change(i); 8 System.out.println("c: i=" + i); 9 10 System.exit(0); 11 } 12 13 private static void change(Integer i) { 14 int value = i + 2; 15 i = new Integer(value); 16 System.out.println("b: i=" + i); 17 } 18 }
运行程序后输出如下信息:
从输出的结果来看,在change()方法中修改了 i 变量的值,但这种修改并未带出方法外,退出change()方法后,i 的值还是1。参数 i 是integer的对象类型,按理传入的是对象引用,修改了数据能够带出来才对,这是怎么回事呢?我们需要分析一下在main函数中调用change()方法时具体传入的是什么,在change()方法中又修改了什么。
调用方法时传递参数,本质上是做数据拷贝。只不过传值是拷贝对象内容,传引用拷贝的是对象地址。上面的方法调用过程中将 i 变量的地址传递到了change()方法中,即传递的是一个32位的指针(64位的操作系统,指针是64位的);在change()方法中定义了一个变量 i 来存储这个地址(注意的是在change方法中的变量 i 与main方法中的变量 i 不是同一个变量,只是它们一开始都指向了一个值为1的变量空间)。
既然两个 i 不是相同的变量,那么在change()方法中通过new新申请一片空间给 i 赋值,只是让change()方法内的 i 变量指向一个新地址,对main方法中 i 变量无影响,也就不会改变它所指向地址空间中存储的值。
在C++代码中调试印证
在JAVA中看不到变量的地址,把上面的代码逻辑放到C++中调试一下就很清空了。
1、可以看到一开始p指针指向的int型变量的地址是0x06bd5398:
2、p变量本身的地址是0x0031efac, 即指向指针的指针是0x0031efac:
3、调用change()后,可以看到参数p的值是0x06bd5398:
4、p变量本身的地址变为0x0031ef70,说明change()函数定义了一个新的指针变量,与main中的p指针指向了同一个int变量。
基于上面的分析,在change()中重新分配一个int对象,使用p指针指向它。改变这个新分配变量的值,不会影响到main中分配的那个int变量的值。