java函数传参:都是传的拷贝!
先说结论:Java中传参都是传的拷贝值,不同的是:基本类型,传的是值的拷贝;对象,传的是引用的拷贝。
我们先来看一个例子:
猜测一下输出值是什么?
结果:
int没有发生变化而Student的实例s的却发生了变化!为什么?
一点一点来理:
1.引用菜鸟中的解释
基于java一切皆对象的思想,自我理解就是 8大基本类型和非8大基本类型 (比一定正确)
2.变量的基本类型和引用类型的区别
基本数据类型在声明时系统就给它分配空间:
如:int a=0;//生命时即分配拉内存空间;
引用则不同,它声明时只给变量分配了引用空间,而不分配数据空间:
如:Student的实例变量s,生命时为s分配了引用空间。
注意:"引用"也是占用空间的,一个空Object对象的引用大小大概是4byte;
3.值传递和引用传递
不同的数据类型在函数传值是方式也不一样:
(1)值传递:
方法调用时,实际参数把它的值传递给对应的形式参数,函数接收的是原始值的一个copy副本,此时内存中存在两个相等的基本类型,即实际参数和形式参数,后面方法中的操作都是对形参这个值的修改,不影响实际参数的值。
(2)引用传递:
也称为传地址。方法调用时,实际参数的引用(地址,而不是参数的值)被传递给方法中相对应的形式参数,函数接收的是原始值的内存地址;在方法执行中,形参和实参内容相同,指向同一块内存地址,方法执行中对引用的操作将会影响到实际对象。
看了这些你应该就明白上面输出结果的原因了吧,简单的说就是:getInt方法中传入的i只是i的值0的一个copy,所以它的修改不会影响i本身的值,而传入的实例变量s则传入的是s的地址,所以在方法中的修改映射到s本身。
j结论就是:基本类型传参是传的copy值,所以方法(即getInt方法)内的修改(j=20)不影响参数(即i)本身,而引用类型传递的是引用地址,方法(getInt)内的修改(stu.setAge(18))会映射到方法外传入参数(s)的而本身,
但是,很容易会让人走入一个误区,基本类型传的是copy值,引用类型传递的是地址本身。但其实引用类型传递的也是copy值,不过它是传的地址的copy值,所以如果你在方法中修改了地址copy值的指向,你在对地址copy值进行修改时不能映射到实例变量本身的。
一起看下面一个例子:
猜测一下输出结果是什么?结果是:
如果还不能理解的话请看下面两个链接:
字节码解析引用传递和值传递: