针对这个问题,首先我们要知道什么是值传递,什么是引用传递。
- 值传递是指在调用函数时将实际值复制一份副本,然后将副本传递到函数中去,这样函数对参数修改实际上对副本的修改,不会影响到实际参数。
- 引用传递是指在调用函数时将地址传递到函数中,函数对参数的修改自然会影响到实际参数。
总之,一句话概括值传递和引用传递的区别就是:
值传递传递是实际值的副本,不会影响实际值;引用传递传递是实际参数的地址,函数会修改实参。
有了这个概念,我们来看一段程序,看它输出结果如何。
class Fruit{ int i=0; } public class BookTest{ public static void main(String[] args){ int a=0; Fruit f=new Fruit(); System.out.println("Before Change"); System.out.println(a); System.out.println(f.i); change(f,a); System.out.println("After Change"); System.out.println(a); System.out.println(f.i); } static void change(Fruit f, int i){ f.i++; i++; } }
输出的结果如下:
Before Change
0
0
After Change
0
1
从结果来看,我们不难得出这样的结论:基本类型是值传递,引用类型是引用传递。
但实际上这个结论正确码?
我们对上面的代码在增加两行新的内容。
class Fruit{ int i=0; } public class BookTest{ public static void main(String[] args){ int a=0; Fruit f=new Fruit(); System.out.println("Before Change"); System.out.println(a); System.out.println(f.i); System.out.println(f); change(f,a); System.out.println("After Change"); System.out.println(a); System.out.println(f.i); System.out.println(f); } static void change(Fruit f, int i){ f.i++; i++; } }
输出的结果如下:
Before Change
0
0
class1.Fruit@15db9742
After Change
0
1
class1.Fruit@15db9742
我们看到,经过函数处理后,句柄f的地址并没有发生任何的改变。我们区分值传递还是引用传递的依据是实参有没有改变,对于f实参地址才是它的地址!所以对于f它的实参也没有改变,它应该也属于值传递。
获取上面的代码还不够直接显示引用类型也是值传递,我们看一下代码
class Fruit{ int i=0; } public class BookTest{ public static void main(String[] args){ int a=0; Fruit f=new Fruit(); System.out.println("Before Change"); System.out.println(a); System.out.println(f.i); System.out.println(f); change(f,a); System.out.println("After Change"); System.out.println(a); System.out.println(f.i); System.out.println(f); } static void change(Fruit f, int i){ f=new Fruit(); f.i++; i++; } }
输出结果:
Before Change
0
0
class1.Fruit@15db9742
After Change
0
0
class1.Fruit@15db9742
是不是从这个代码中更能体现引用类型传递是实际地址的副本,而不是实际地址。
所以说Java中只有值传递没有引用传递。
--------------------------------------------------------------------------------------------------------
参考博文:https://blog.csdn.net/u014745069/article/details/86649062