1、传值还是传址?
传值,没有传址这一说,参数的传递传递的始终都是一个值。
2、参数传递内存分析
①当参数是基本数据类型的数据,如下代码
public class test04 {
public static void main(String[] args) {
test04 t4=new test04();
int data=10;
t4.sys(data);
System.out.println("主方法中的data变量="+data);
}
public void sys(int data){
data++;
System.out.println("sys方法中的data变量="+data);
}
}
输出结果如下:虽然在调用方法sys中对局部变量data的值进行了自加操作,但是很明显,main方法中作为实参的data变量的值并没有发生改变,这是因为两个data并不代表同一个内存单元;
sys方法中的data变量=11
主方法中的data变量=10
Process finished with exit code 0
进行内存分析:
main方法中和sys方法中的内存单元是两个内存单元,传递过去的只有字面值10,传递结束后,两边的任何操作,互不相扰。
②当参数是引用数据类型,代码如下:
public class test04 {
int data; //定义成员变量
public static void main(String[] args) {
test04 t4=new test04();
t4.data=10;
System.out.println("在执行sys方法前,主方法中的data变量="+t4.data);
sys(t4);
System.out.println("执行完sys方法后,主方法中的data变量="+t4.data);
}
public static void sys(test04 t4){
t4.data++;
System.out.println("sys方法中的data变量进行自加一操作后data="+t4.data);
}
}
输出结果:很明显,在sys中对传递过来的对象的data变量进行修改之后,原对象的值也发生了变化。
在执行sys方法前,主方法中的data变量=10
sys方法中的data变量进行自加一操作后data=11
执行完sys方法后,主方法中的data变量=11
Process finished with exit code 0
进行内存的分析:
参数传递的时候传递的是一个引用t4,那么这个引用作为一个变量,存储的是在堆内存中test04类型对象的内存的地址,这个地址其实也是一个普通的值,不需要把地址进行特殊化理解。
那么当调用方法的时候,可以发现sys方法中的形参是一个和实参同类型的引用,当将实参的引用(变量)传递给形参的时候,形参变量接收传过来的值,这个实际上就是一个赋值的操作。
当赋值结束后,因为形参变量是一个引用,并且其值是存的在堆内存中test04类型对象的内地址,那么这个引用就会指向那个内存单元。
所以形参和实参两个引用类型的变量指向的是同一块内存单元,这时候通过两个引用去访问的都是同一个内存单元,所以操作会互相的产生影响,data的值从主方法中获取到的,和从sys方法中获取到的都是同一个修改之后的值。
3、总结
参数的传递只有传值一种,所说的传址其实也是传值,只不过传的是地址值,也是一个普通的数值。
注意变量自身也是占据内存的,例如:
test04 t4=new test04();
t4作为一个局部变量也是会占据内存的,上述代码中的其实是,有点像指针的指针