Zacard's Notes

java是值传递还是引用传递

java到底是值传递还是引用传递

“Java manipulates objects ‘by reference,’ but it passes object references to methods ‘by value.’” –David Flanagan

大神解释了:java操作对象都是通过引用传递,而给方法传参都是通过值传递

首先,操作对象通过引用传递这个大家应该没有什么争议。但是方法传参都是通过值传递,估计大家还有些疑虑。

代码验证

我们知道,如果是值传递,那么实际上传的是一份拷贝。引用传递的话一般传递的是内存地址(看具体的jvm实现)。
所以,值传递是无法修改原值的,而引用传递是可以修改原值。

请看以下代码例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
@Test
public void testPassedByValueOrReference() {
char[] c1 = {'a','b'};
change1(c1);
System.out.println("c1 after change1:" + Arrays.toString(c1));
change2(c1);
System.out.println("c1 after change2:" + Arrays.toString(c1));
}
private void change1(char[] c1) {
char[] c2 = {'e','f'};
c1 = c2;
}
private void change2(char[] c1) {
char[] c2 = {'e','f'};
c1[0] = c2[0];
}

输出:

c1 after change1:[a, b]

c1 after change2:[e, b]

我们知道,数组是个对象。传递给2个不同的方法,确出现了不一致的行为,既有点像值传递,有好像是引用传递。我们来看看这2个方法在内存中到底做了什么:

change1()方法在内存中的执行过程:

change2()方法在内存中的执行过程:

所以很清楚了,首先,对于方法的传参确实都是值传递,传递的总是拷贝(对象传递的是引用的拷贝,基础类型为原值的拷贝)。当方法中试图改变这个应用所指向的对象时,其实改变的仅仅是这个引用的拷贝,原引用(引用指向的对象)没有任何变化。而当方法改变的是这个引用拷贝所指向的对象内容(假设对象是可变的)时,原引用由于指向的是同一个对象,所以也会受影响。这其实就是java方法有“副作用”的原因。

坚持原创技术分享,您的支持将鼓励我继续创作!

热评文章