Java中只有按值传递,不存在按引用传递

值传递!Java中只有按值传递,不存在按引用传递!

- 按值传递是什么 ?
指的是在方法调用时,传递的参数是按值的拷贝传递。方法调用时,实参把它的值传递给对应的形参,形式参数只是用实际参数的值初始化自己的存储单元内容,是两个不同的存储单元,所以方法执行中形式参数值的改变不影响实际参数的值。
- 按引用传递是什么?
指的是在方法调用时,传递的参数是按引用进行传递,其实传递的引用的地址,也就是变量所对应的内存空间的地址。方法调用时,实参是对象(或数组),这时实参与形参指向同一个地址,在方法执行中,对形式参数的操作实际上就是对实际参数的操作,这个结果在方法结束后被保留了下来,所以方法执行中形式参数的改变将会影响实际参数。

值传递与引用传递的关系如下图所示:
这里写图片描述

java值传递的示例:

//定义了一个改变参数值的函数  
public static void changeValue(int x) {  
x = x *7;  
}  
... ...  
//调用该函数  
int num = 5;  
System.out.println(num);  
changeValue(num);  
System.out.println(num); 

由此做一个引子,我用图表描绘一个值传递的过程:
这里写图片描述

接下来,就来看java中的对象参数是怎么传递的:

同样,先给出一段代码:

class person {  
public static String name = "Jack";  
... ...  
}  
... ...  
//定义一个改变对象属性的方法  
public static void changeName(Person p) {  
p.name = "Rose";  
}  
... ...  
public static void main(String[] args) {  
//定义一个Person对象,person是这个对象的引用  
Person person = new Person();  
//先显示这个对象的name属性  
System.out.println(person.name);  
//调用changeName(Person p)方法  
changeName(person);  
//再显示这个对象的name属性,看是否发生了变化  
System.out.println(person.name);  

结果如下:
第一次显示:“Jack”
第二次显示:“Rose”

方法用了一个对象参数,该对象内部的内容就可以改变,我之前一直认为应该是该对象复制了一个引用副本给调用函数的参数,如上图引用传递示意图那样,使得该方法可以对这个对象进行操作,然而这是不对的!

为什么这里是“值传递”,而不是“引用传递”?

这里写图片描述

主函数中new 了一个对象Person,实际分配了两个对象:新创建的Person类的实体对象(堆内存),和指向该对象的引用变量person(栈内存)。
【注意:在java中,新创建的实体对象在堆内存中开辟空间,而引用变量在栈内存中开辟空间】

正如如上图所示,左侧是堆空间,用来分配内存给新创建的实体对象,红色框是新建的Person类的实体对象,000012是该实体对象的起始地址;而右侧是栈空间,用来给引用变量和一些临时变量分配内存,新实体对象的引用person就在其中,可以看到它的存储单元的内容是000012,记录的正是新建Person类实体对象的起始地址,也就是说它指向该实体对象。

这时候,好戏上台了:
调用了changeName()方法,person作为对象参数传入该方法,但是大家特别注意,它传入的是什么!!!person引用变量将自己的存储单元的内容传给了changeName()方法的p变量!也就是将实体对象的地址传给了p变量,从此,在changeName()方法中对p的一切操作都是针对p所指向的这个存储单元,与person引用变量所指向的那个存储单元再没有关系了!

回顾一下上面的一个值传递的例子,值传递,就是将存储单元中的内容传给调用函数中的那个参数,这里是不是异曲同工,所以java是“值传递”,而非“引用传递”!!!

那为什么对象内部能够发生变化呢?

那是因为:p所指向的那个存储单元中的内容是实体对象的地址,使得p也指向了该实体对象,所以才能改变对象内部的属性,所以看似是引用传递,实际本质上java通过值传递,实参把实体对象的地址通过值传递传给形参,形参再取出该内容通过实体对象的地址去操作实体对象!

这也是我们大多数人会误以为是“引用传递”的终极原因!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值