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、日常编程并无不可。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,767评论 18 399
  • 集合框架: 1)特点:存储对象;长度可变;存储对象的类型可不同2)Collection(1)List:有序的;元素...
    Demo_Yang阅读 1,286评论 0 4
  • 1. 面向对象的特征有哪些方面? 抽象:抽象是将一类对象的共同特征总结出来构造类的过程,包括数据抽象和行为抽象两方...
    程序熊大阅读 4,485评论 6 74
  • 1、.java源文件: 一个以”.java“为后缀的源文件:只能有一个与文件名相同的类,可以包含其他类。 2、类方...
    Hughman阅读 1,524评论 1 9
  • 朗读者第四期,倪萍朗读了她写的姥姥语录。 天黑了就是遇上挡不住的大难了,你就得认命。人命不是撂下(放弃),是咬着牙...
    橙心绿思阅读 383评论 0 2