Java中只有值传递,很多人看到这个结论都会有疑问,值传递和引用传递的区别是什么?Java中只有值传递,没有引用传递的话,那对我们调用方法传对象类型的参数,会有什么影响?

  下面我们先来复习下值传递和引用传递。

值传递和引用传递

  • 值传递(pass by value):指在调用函数时,将实际参数复制一份传递到函数中。
  • 引用传递(pass by reference):指在调用函数时,将实际参数的地址直接传递到函数中,那么在函数中对参数进行修改,将影响到实际参数。

值传递

引用传递

根本区别

会创建副本

不创建副本

结果

函数中无法改变原始对象

函数中可以改变原始对象

  了解到两者区别后,下面通过3个例子说明。

例子1:传递基本类型参数

  代码示例:

public class t1 {

    public static void main(String[] args) {
        int i = 10;
        t1.pass(i);
        System.out.println("print in main , i is " + i);
    }
    public static void pass(int i) {
        i = 20;
        System.out.println("print in pass , i is " + i);
    }
}

  输出:

java不定参数函数 传给不定参数的数据 java参数传递只存在值传递_开发语言

  可以看到,pass()方法中,对i成功重新赋值,但对main主线程中的i并没有影响。这是因为t1.pass(i)这个调用过程,只是将i的副本传递给了pass()。所以,对于基本类型,Java中是值传递。

  如果传入的是对象类型呢?请看下面的例子2。

例子2:传递引用类型参数

  代码示例:

public class t2 {

    public static void main(String[] args) {
        String name = "jinyj";
        t2.pass(name);
        System.out.println("print in main , name is " + name);
    }
    public static void pass(String name) {
        name = "jinyj2";
        System.out.println("print in pass , name is " + name);
    }
}

  输出:

java不定参数函数 传给不定参数的数据 java参数传递只存在值传递_开发语言_02

  可以看到,pass()方法中,对对象name重新赋值后,main主线程中的name仍然没有影响。同样的,t2.pass(name)的调用,也只是将name的副本传递给pass()。所以,对于对象类型,Java也是值传递。

  如果都是值传递,那是不是我们对方法中传入的对象,无论做怎样的修改,都不会影响原本的对象呢?请看下面的例子3。

例子3:传递引用类型参数2

  代码示例:

public class t3 {

    public static void main(String[] args) {
        User user = new User();
        user.setName("jinyj");
        user.setAge(18);
        t3.pass(user);
        System.out.println("print in main , user is " + user.getName());
        System.out.println("print in main , user is " + user.getAge());
    }
    public static void pass(User user) {
        user.setName("jinyj2");
        user.setAge(19);
        System.out.println("print in pass , user is " + user.getName());
        System.out.println("print in pass , user is " + user.getAge());
    }
}

class User {
    String name;
    int age;

    // 此处省略字段的Getter、Setter方法
}

  输出:

java不定参数函数 传给不定参数的数据 java参数传递只存在值传递_java_03

  如图,pass()方法中对对象user字段的修改,无论是基本类型的字段age,还是对象类型的name,都对原对象user造成了影响。这是因为t3.pass(user)的调用中,虽然传递的是user的副本,即user指针地址的副本,但pass()方法内部执行的操作是对user字段的修改,也就是user指针地址所指向的具体内容,虽然是user指针地址的副本,但指向的内容是一致的,所以修改会对原对象有影响。