Java中参数传递方式(按值传递还是引用传递)
先看程序员都熟悉的值传递:把基本类型传进方法,方法里改的是副本,调用方变量不会变。Java 里对象参数同样是值传递——传的是引用的副本,不是把引用变量本身搬过去。
所以:方法里能改对象内部状态,却改不了调用方那个引用变量指向谁。下面用两段代码和两张原图说明。
一、基本类型:传的是存储单元里的内容
调用前后 num 都是 5。过程如图:
num 传给 changeValue 时,是把 num 那个存储单元里的值 5 拷给方法里的 x,x 另有自己的存储单元。之后对 x 的操作与 num 无关。值传递的精髓是:传递存储单元中的内容,而不是地址把柄本身。
二、对象参数:仍然是值传递
第一次打印 Jack,第二次 Rose。很多人以为方法收到的是引用本身,其实收到的是引用的副本。
http://www.cnblogs.com/clara/archive/2011/09/17/2179493.html 写道:Java 只有值传递。对象实例作为参数时,参数的值是该对象引用的一个副本,指向同一个对象。对象内容可以在被调方法里改变,但调用方的引用(不是副本)永远不会被改掉。
new Person() 实际涉及两块:堆里的实体对象,和栈里的引用变量 person。图中左侧堆、红色框是实体、起始地址 000012;右侧栈里 person 存的正是 000012。
调用 changeName(person) 时,person 把自己存储单元里的内容(实体地址)传给方法参数 p。此后对 p 的操作针对 p 自己的那一格,与 person 那一格无关——这和基本类型把 5 拷走是同一件事,所以仍叫值传递,不是引用传递。
对象内部能变,是因为 p 里存着实体地址,p 也指向同一块堆内存,于是能改属性。这正是误以为“引用传递”的原因。
| 传递什么 | 方法里改副本 | 调用方看得到的效果 |
|---|---|---|
| 基本类型的值 | 改的是方法里的 x | 调用方 num 不变 |
| 对象引用的副本(地址值) | 改 p 指向谁,不影响 person | 改 p 所指对象的字段,调用方能看见 |
一句话总结:Java 只有值传递:基本类型拷数值,对象拷引用副本;能改对象内容,改不了调用方那个引用变量。
转载请注明来源:Java中参数传递方式(按值传递还是引用传递)









