值传递和引用传递

  • 碎碎念
  • 基本概念
  • 形参
  • 实参
  • 值传递
  • 引用传递
  • Java只有值传递
  • 实例讲解
  • 当参数为基本数据类型
  • 当参数为对象,实参未更新
  • 当参数为对象,实参更新


碎碎念

面试时经常会被问:值传递和引用传递的区别?甚至会出一道编程题,让你写出正确答案。例如以下代码会打印什么?

public static void main(String[] args) {
        StringBuffer a = new StringBuffer("A");
        StringBuffer b = new StringBuffer("B");
        op(a, b);
        System.out.println(a + "," + b);
    }

    static void op(StringBuffer a, StringBuffer b) {
        a.append("B");
        b = a;
    }

答案是打印"AB,B"。如果做对了,恭喜你!
我们下面进入理论殿堂,讲讲原因。

基本概念

形参

用来接收调用该方法时传递的参数。

实参

传递给调用方法的参数。

public static void main(String[] args) {
        int  x = 1;
        // 此处 x 为实参
        opInt(x);
    }
    
     // 此处 a 为形参
    static void opInt(int a) {
        a = 5;
    }

值传递

调用方法时,将实际参数复制一份到该方法中。

引用传递

调用方法时,将实际参数的地址传入该方法中。

Java只有值传递

首先,必须明确一点:Java只有值传递。
这个问题在国外也争论的很厉害,不过官方给出答案了:Java只有值传递。
从概念上也很好理解:

  • 基本数据类型的数据保存在栈中,可直接获取。
  • 对象的数据保持在堆中,需要通过引用地址获取实际数据。
  • 基本数据类型传递时,形参会复制实参的值。
  • 对象传递时,形参会复制实参的引用地址。
    但注意了,两个方式都说复制,也就是对象传递时,并没有把实参的引用地址传入该方法,而是复制了一份。

因此,Java只有值传递。

实例讲解

下面通过3个实例来讲解。

当参数为基本数据类型

public static void main(String[] args) {
        int  x = 1;
        opInt(x);
        System.out.println(x);
    }
    
    static void opInt(int a) {
        a = 5;
    }

打印结果:“1”。

结论:当参数为基本数据类型时,修改形参的值,不会影响实参。因为形参仅拷贝了实参的值。

java类之间数据传递_引用传递

当参数为对象,实参未更新

public static void main(String[] args) {
        StringBuffer x = new StringBuffer("A");
        op(x);
        System.out.println(x);
    }

    static void op(StringBuffer a, StringBuffer b) {
       a = new StringBuffer("B");
    }

打印结果:“A”。

结论:当参数为对象时,修改形参的引用,不会影响实参。因为形参仅指向了实参的引用地址。" a = new StringBuffer(“B”);"操作把变量a指向了新的对象。

java类之间数据传递_Java_02

当参数为对象,实参更新

public static void main(String[] args) {
        StringBuffer x = new StringBuffer("A");
        op(x);
        System.out.println(x);
    }

    static void op(StringBuffer a, StringBuffer b) {
       a.append("B");
    }

打印结果:“AB”。

结论:当参数为对象时,修改形参的指向的值,实参也会更新。因为形参指向了实参的引用地址,修改了该地址对应的值,所有该值的引用对象都会同步更新。

java类之间数据传递_引用传递_03


看到这里,第一道编程题打印“AB,B”是否能理解了呢?