Java究竟是值传递还是引用传递

针对这个问题,首先我们要知道什么是值传递,什么是引用传递。

  • 值传递是指在调用函数时将实际值复制一份副本,然后将副本传递到函数中去,这样函数对参数修改实际上对副本的修改,不会影响到实际参数。
  • 引用传递是指在调用函数时将地址传递到函数中,函数对参数的修改自然会影响到实际参数。

总之,一句话概括值传递和引用传递的区别就是:

值传递传递是实际值的副本,不会影响实际值;引用传递传递是实际参数的地址,函数会修改实参。

有了这个概念,我们来看一段程序,看它输出结果如何。

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

原文地址:https://www.cnblogs.com/Jerryoned/p/13227636.html