Java 值传递问题

前提

值传递和引用传递

值传递:

  • 当一个参数被传递给方法时,方法接收的是这个参数值的一个副本。
  • 方法内部对这个副本的任何修改,都不会影响到原始参数。

引用传递:

  • 当一个参数被传递给方法时,方法接收的是这个参数的内存地址。
  • 方法内部可以通过这个 自己直接修改原始参数的值。

Java的数据类型

Java 的变量分 2 种:

  • 基本数据类型:short/int/long/float/double/char/boolean/byte
    • 变量中存储的是值本身。
  • 引用数据类型:String/Object/ArrayList 等
    • 变量存储的是一个引用,这个引用指向内存中实际对象所在的地址。

Java只有值传递

Java 的方法参数传递永远是变量的值。如果变量是基本数据类,则传递数据的值;如果变量是引用类型,则传递引用地址值。

场景

传递基本数据类型

public class Main {
    public static void main(String[] args) {
        int x = 10;
        System.out.println("修改前 x=" + x);
        changeValue(x);
        System.out.println("修改后 x=" + x);
    }

    public static void changeValue(int x) {
        x = 100;
        System.out.println("changeValue x=" + x);
    }
}

// 修改前 x=10
// changeValue x=100
// 修改后 x=10

说明:changeValue() 方法接收到的是原始值的副本,对副本的修改不会影响原始值。

传递引用数据类型

class Person {
    String name;

    public Person(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                '}';
    }
}

public class Main {
    public static void main(String[] args) {
        Person person = new Person("小白");
        System.out.println("修改前 person=" + person);
        changeValue(person);
        System.out.println("修改后 person=" + person);
    }

    public static void changeValue(Person p) {
        p.name = "小黑";
        System.out.println("changeValue person=" + p);
    }
}

// 修改前 person=Person{name='小白'}
// changeValue person=Person{name='小黑'}
// 修改后 person=Person{name='小黑'}

说明:

  • 运行 main() 方法,创建了一个 Person 对象,在内存中分配一块空间给它,person 变量指向这个对象的内存地址。
  • 调用 changeValue() 方法时,person 变量的地址值复制了一份,传递给 changeValue() 的形参 p。
  • 这时虽然 person 和 p 是2 个不同的变量,但是都指向同一个对象的地址值,因此修改 p.name 时,该对象的 name 属性也发生修改了。
  • changeValue() 方法执行完后,副本变量 p 被销毁了,main() 方法中的 person 变量再次访问该对象时,看到的就是修改后的状态。

无法修改引用本身

public class Main {
    public static void main(String[] args) {
        Person person = new Person("小白");
        System.out.println("修改前 person=" + person);
        changeValue(person);
        System.out.println("修改后 person=" + person);
    }

    public static void changeValue(Person p) {
        p = new Person("小黑");
        System.out.println("changeValue person=" + p);
    }
}

// 修改前 person=Person{name='小白'}
// changeValue person=Person{name='小黑'}
// 修改后 person=Person{name='小白'}

说明:

  • changeValue() 接收 person 变量的副本 p,接着执行 p = new Person() ,表示创建一个新的 Person 对象,并让副本 p 指向这个新对象。
  • 不会影响到 main() 中的原始 Person 对象。
Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐