java 引用深度,Java值传递与引用传递深度解析

众所周知,Java存在8种基础数据类型。

不过,Java字节码中还有额外的两种基础数据类型,分别是reference type与returnAddress type。

想要学习Java 中的参数传递,就必须理解JVM是如何解释基础数据类型与引用数据类型的。

一切皆数据?一切皆对象?

我们先从最基础的赋值开始:

Object A = new Object();

new Object() 做了什么?

JVM将在GC堆中开辟一定大小的空间用以存放此Object,此Object是引用数据类型(注意不是reference类型)。

Object A 做了什么?

JVM将在虚拟机栈中此线程栈开辟出一个slot用以存放A,注意此处A为reference type。(slot可以理解为用以存放基础数据类型的线程私有的空间)

“ = ” 做了什么?

reference type 的A被赋值为先前new Object() 指令所产生的引用数据类型的一个对象。

案例分析

static String s1 = "abc" ;

public static void changeString(String s2){

s2="bcd";

}

changeString(s1);

运行以上代码,s1改变了吗?

答案是没有。

为什么呢?

因为JVM中传递的不是reference本身,而是reference的拷贝。

或者你可以理解为传递的是一个int类型的数据,不过这个int类型比较特殊,里面存放有一个对象的地址。

我们来一步一步分析上面的代码:

String s1 = "abc";

//JVM开辟了一定大小的空间用以存放一个String对象,我们假设这个空间的起始值为0x8000。那么reference类型的s1就被赋值为0x8000。

void changeString(String s2){

//JVM中传递的是基础数据类型reference ,此时开辟一个线程帧,为s2开辟一个slot,其值与s1相同,为0x8000

s2="bcd";

// 我们假设“bcd”的地址为0x9000,那么s2作为一个reference类型的数据将被赋值为0x9000

}

所以,函数changeString() 所做的只是新建了一个reference类型的数据s2,然后把“bcd”的地址赋值给了s2,对于s1和s1所指向的对象“abc”没有做任何事,我们当然也看不到任何改变了。

综上所述,JVM中传递的所有数据都是基础数据类型的数据,只是JVM会解析这是一个普通的数据类型还是 reference type 或 returnAddress type 。

所以,所有对形如s2这样的传入reference进行 = 的赋值,都不会改变s1的数据,即s1依然会指向原来的对象。

用不太严谨的话来说:Java中传递引用数据类型本质是传递其地址的拷贝。

所以,才说Java中只有值传递。

不过,值传递与引用传递并不能完全区分来看,将引用数据类型看做是传递引用对于理解Java、日常编程并无不可。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值