所谓值传递指的是将变量的一个备份传过去,当该备份被修改后,不会影响原来变量的值; 而引用传递指的是将该变量的地址传过去,当值修改后,原来的变量也会相应的修改; 如: 值传递: int a=1; void Input(int a) { a=2; } Console.WriteLine(a);//此时a=1 -------------------------------------- 引用传递: int a=1; void Input(ref int a) { a=2; } Console.WriteLine(a);//此时a=2
本质上讲,java 其实都是传值对于基本数据类型,它是传值,其实就是在调用方法时把一个数值复制一份放到参数列表中,然后被调用的方法从这个列表中读取数据对于对象类型,虽然说它是传引用,但其实参数中存放的是对象的地址,被调用的方法得到的也是对象地址的一个副本而已 以传引用为例,打个比方: Person obj = new Person("张三");那么 obj 这个变量其实存放的是一个 Person 对象的地址如果我调用了一个方法:f(obj); 这相当于我把张三的地址写在一张小纸条上,然后把这张小纸条放到 f 方法中;而在 f 方法内部,可以根据小纸条上的地址找到张三这个人。
而引用传递指的是将该变量的地址传过去,当值修改后,原来的变量也会相应的修改;
如:
值传递:
int a=1;
void Input(int a)
{
a=2;
}
Console.WriteLine(a);//此时a=1
--------------------------------------
引用传递:
int a=1;
void Input(ref int a)
{
a=2;
}
Console.WriteLine(a);//此时a=2
保存对象的数据,虽然是副本,但地址是唯一的。好比我拿你家地址的原件或复印件都能
找到你家。所以对改地址进行操作会同样改变原对象。但传递的并不是原对象本身。所以,如果函数内的对象指向新的地址,并不会改变原对象的地址。其实一般认为,java内的传递都是值传递。只是传递的内容不同罢了。
例如int a, b;
a = 3;
b = a; 字节码为0 iconst_3
1 istore_1 [a]
2 iload_1 [a]
3 istore_2 [b]
引用类型变量的传递是传递就是引用传递了,传递的是该对象的一个引用。
例如Integer a,b;
a=new Integer(3);
b=a;字节码为 0 new java.lang.Integer [16]
3 dup
4 iconst_3
5 invokespecial java.lang.Integer(int) [18]
8 astore_1 [a]
9 aload_1 [a]
10 astore_2 [b]细心的话你会发现,本质上是一样的:
一个是
istore_1 [a]
iload_1 [a]
istore_2 [b]
一个是
astore_1 [a]
aload_1 [a]
astore_2 [b]
只不过由于在后者传递的本身是引用,所以被称为引用传递,其实java内的传递都是值传递。
但注意引用传递后发生了别名现象,a,b操纵的是同一个对象
所以,java传递的一定是数值,但是,C++的引用,也是传递的数值(地址也是一个数值)不是么? 为什么C++就叫“引用传递”呢? 那是因为C++编译器,你写了这样的代码,它就把代码编译成好像真的把对象传递过去一样的汇编代码。
因此,这个问题其实就是不同的语言,含义不同。没有理由,在C++里就遵守C++的参数传递规则;在Java里就记住java的参数传递细节。 另外记住,“Java都是值传递”这个结论。
传值调用)。因此,很多书里面都说Java是进行传值调用,这点没有问题,而且也简化的C中复杂性。
但是传引用的错觉是如何造成的呢?在运行栈中,基本类型和引用的处理是一样的,都是传值,所以,如果
是传引用的方法调用,也同时可以理解为“传引用值”的传值调用,即引用的处理跟基本类型是完全一样的。
但是当进入被调用方法时,被传递的这个引用的值,被程序解释(或者查找)到堆中的对象,这个时候才对应
到真正的对象。如果此时进行修改,修改的是引用对应的对象,而不是引用本身,即:修改的是堆中的数据。
所以这个修改是可以保持的了
以传引用为例,打个比方:
Person obj = new Person("张三");那么 obj 这个变量其实存放的是一个 Person 对象的地址如果我调用了一个方法:f(obj);
这相当于我把张三的地址写在一张小纸条上,然后把这张小纸条放到 f 方法中;而在 f 方法内部,可以根据小纸条上的地址找到张三这个人。
引用传递指的是方法接收的是调用者提供的变量地址。
java是采用值传递的,即方法得到的是所有参数值的一个拷贝,因此方法不能修改传递给它的任何参数变量的值。
但当参数是对象时,java传递的是一个对象引用,即是原有对象引用的一个拷贝,因此,当改变其值时,可以改变原有对象的参数。
原始类型 传递的就是原始类型本身
1、值传递是直接你写好一个值去给那个方法;
2、引用传递是你写好值对应的变量之后,由构造方法自己去取。