JVM视角:值传递or引用传递?【转】
- 每个新的函数调用指令(通常是invoke*)会创建一个新的栈帧。
- 栈帧中不存在
b
或者i
这种变量名,所有操作都是通过本地变量表和操作数栈完成。 - 在方法体执行完毕之后,通过*return将方法体内部的临时计算结果(通常存放在本地变量表中)返回给调用该方法的方法。如
ireturn
返回一个int,areturn
返回一个引用。在本例中调用foo
的方法是main
方法,而foo
方法直接通过不带任何前缀的return
指令返回,返回的即是一个void
。
因此,在main
方法中b
的值不会改变。我们也可以简单的得出结论:对于引用数据类型,Java传递的确实是引用!
进一步拓展来说,从JVM的层次看,objectref
(对象的引用)会在新帧栈创建时,保存在新栈帧的本地变量表中,而反馈到Java语言层面,类似在函数内部创建了一个形参的副本,以本例来看就是b'
,对于b'
的所有赋值操作都不可能影响到main
方法中的b
,因为无论什么赋值操作,都只是影响foo
方法对应栈帧中的几个本地变量而已。但由于副本b'
保存的内容和b
一样都是指向同样的某一块内存地址,因此在foo
方法内部通过调用字段的setter
方法,可以将内存中某个字段值改变(通过JVM中的putfield
指令),从而反馈到main
方法中。
因此我们可以得到这样的结论:对于基本数据类型,Java传递的是值(这个结论在本文中没有证明);对于引用数据类型,Java传递的是引用。不管传递的是什么,从Java语言层面(相对于JVM)来说都只是传递了一个对应值的副本。
文/elon_wen(简书作者)
原文链接:http://www.jianshu.com/p/76c092cb8d85
著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”。
原文链接:http://www.jianshu.com/p/76c092cb8d85
著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”。