JAVA面试中经常会问到一个“JAVA中是值传递还是引用传递”的问题,今天就记录这个问题的理解。
问题中已经提到了编程语言中的几种值传递方式:值传递和引用传递。首先,我们来看看这两个求值策略的含义:
- 值传递(Call by Value):
在值传递(传值调用)中,实际参数先被求值,然后复制其值传递给被调用函数的形式参数。因为形式参数拿到的是一个拷贝,因此若是在被调用函数中改变了形式参数的值,并不会改变实际参数的值。
- 引用传递(Call by Reference):
在引用传递中,被调用函数的形式参数获得的是实际参数的隐式引用而不是实际参数的副本。因为传递的是引用,如果在被调用函数中改变了形式参数的值,调用者会知晓这种改变。
这里先给出结论:JAVA是值传递,对于对象的形式参数,传递的值就是引用地址。
我们可以看看这个示例代码:
public class ValueTransportation{
public static void main(String[] args){
ValueTransportation vt = new ValueTransportation();
Apple greenApple = new Apple();
greenApple.setColor("green");
vt.passValue(greenApple);
System.out.println("print in main, the apple is "+ greenApple);
}
public void passValue(Apple apple) {
apple = new Apple();
apple.setColor("pink");
System.out.println("print in passValue, the apple is "+ apple);
}
}
相信大家也能知道这里的输出结果,我就直接贴出来:
print in passValue, the apple is Apple{color='pink'}
print in main, the apple is Apple{color='green'}
让我们来一起梳理这里发生了什么:
首先main方法中greenApple对象在堆中获得了一个地址(假设是0x123321),当调用了passValue方法时,形式参数apple获得了这个内存地址的值,运行到
apple = new Apple();时,apple这个变量又指向了内存中另一个地址(假设是0x123322),那这时对apple这个变量的任何改变就不会影响0x123321地址的对象。
所以说,JAVA中只有值传递,只不过传递的内容是对象的引用地址。