JVM视角:值传递or引用传递?【转】

  1. 每个新的函数调用指令(通常是invoke*)会创建一个新的栈帧。
  2. 栈帧中不存在b或者i这种变量名,所有操作都是通过本地变量表和操作数栈完成。
  3. 在方法体执行完毕之后,通过*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
著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”。
posted @ 2016-12-08 16:19  F领主  阅读(314)  评论(0编辑  收藏  举报