Java值传递和引用传递

发布时间 2023-06-29 10:26:54作者: 多见多闻

在Java中,传递参数的方式分为值传递和引用传递。

值传递

在Java中,参数传递是按值传递的,而不是按引用传递。这意味着当你将一个对象作为参数传递给方法时,实际上传递的是对象引用的副本,而不是原始的对象引用。虽然可以通过这个副本访问和修改对象的状态,但不能改变原始的对象引用。

下面是一个例子来说明在Java中不按引用传递的情况:

public class Example {
    public static void main(String[] args) {
        StringBuilder str = new StringBuilder("Hello");
        modifyString(str);
        System.out.println(str); // 输出:Hello World
    }
    
    public static void modifyString(StringBuilder s) {
        s.append(" World");
    }
}

在上述例子中,modifyString 方法接收一个 StringBuilder 对象的副本,并在该副本上进行修改。尽管在 modifyString 方法内部对副本对象进行了追加操作,但这并不会影响到 main 方法中的原始对象 str。因此,在打印 str 时,输出是 "Hello" 而不是 "Hello World"。

这表明 Java 中的参数传递是按值传递的机制,而不是像某些其他编程语言(如C++)那样按引用传递。

引用传递

在Java中,对象类型的变量是存储在堆内存中的对象的引用(即内存地址),而基本数据类型的变量直接存储其值。所以当你将一个对象作为参数传递给方法时,实际上传递的是该对象的引用,因此称为引用传递。

下面是一个简单的例子来说明如何在Java中使用引用传递:

public class Main {
    public static void main(String[] args) {
        int[] arr = {1, 2, 3};
        modifyArray(arr);
        System.out.println(Arrays.toString(arr));
        
        MyClass myObj = new MyClass(10);
        modifyObject(myObj);
        System.out.println(myObj.getValue());
    }
    
    public static void modifyArray(int[] array) {
        // 修改数组的元素值
        array[0] = 100;
    }
    
    public static void modifyObject(MyClass obj) {
        // 修改对象的属性值
        obj.setValue(20);
    }
}

class MyClass {
    private int value;
    
    public MyClass(int value) {
        this.value = value;
    }
    
    public int getValue() {
        return value;
    }
    
    public void setValue(int value) {
        this.value = value;
    }
}

运行以上代码会输出以下结果:

[100, 2, 3]
20

modifyArray方法中,我们修改了传入的数组的第一个元素的值。在modifyObject方法中,我们修改了传入的MyClass对象的属性值。在main方法中,我们可以看到这些修改在原始数组和对象上都生效了。

需要注意的是,虽然引用传递传递的是对象的引用,但无法修改传递过来的引用本身。也就是说,在modifyObject方法中,如果将obj重新赋值为另一个对象,这个改变不会影响到原始对象。因为虽然obj和原始对象引用的是同一个内存地址,但是重新赋值后,obj引用的是一个新的内存地址。