Java到底是值传递还是引用传递????

在搞懂这个问题之前, 我们要首先了解什么是值传递, 什么是引用传递?

  • 值传递: 传递的是数据的副本,修改副本不会影响原始数据。
  • 引用传递: 传递的是数据的引用(地址),修改引用会直接影响原始数据.

也就是说,值传递和引用传递最大的区别是传递的是自身,还是复制的副本,如果传递的是自身则为引用传递,如果传递的是复制的副本则为值传递。

但是在Java语言中, 只有值传递, 没有引用传递

下面我们看一个例子, 传递基本数据类型 int 的参数, 之后再修改传递的参数, 然后打印结果

java 复制代码
package value_propagation;

public class Test01 {
    public static void main(String[] args) {
        int a = 333;
        System.out.println("调用方法之前: " + a);
        change(a);
        System.out.println("调用方法之后: " + a);
    }

    public static void change(int number) {
        number = 666;  // 修改 number 的值
    }
}

看上面结果可以知道 int 是值传递, 传递的只是个副本, 并没有修改原始值

然后我们传递一个对象(引用类型) 试试

java 复制代码
package value_propagation;

public class Test02 {
    public static void main(String[] args) {
        Integer a = new Integer(333);
        System.out.println("调用方法之前: " + a);
        change(a);    // change(a) 传递的是 a 引用的副本
        System.out.println("调用方法之后: " + a);
    }

    public static void change(Integer number) {
        number = 666;  // 修改 number 的值,
    }
}

在 change 方法中,number 是局部变量,它接收到 a 引用的副本。 因此,当你修改 number 为 666 时,实际上只是改变了 number 这个局部变量的引用指向的内容。这并不会影响外部的 a,因为 a 和 number 是两个不同的引用。 a 仍然指向 Integer 对象 333,而 number 只是一个局部的副本。

下面我们看一个有争议的传递, 传递一个数组

java 复制代码
package value_propagation;

public class Test03 {
    public static void main(String[] args) {
        int[] arr = {1, 2, 3, 4};
        System.out.print("调用方法之前: ");
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i] + " ");
        }
        change(arr);
        System.out.print("\n调用方法之后: ");
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i] + " ");
        }
    }

    public static void change(int[] array) {
        array[2] = 666;
    }
}

这是不是说明Java支持引用传递呢?
并不是。这里在参数传递的过程中,只是把实参的地址拷贝了一份传递给形参. update方法中只修改了参数地址里面的内容,并没有对形参本身进行修改。

下面我们将代码稍加改动

java 复制代码
package value_propagation;

public class Test04 {
    public static void main(String[] args) {
        int[] arr = {1, 2, 3, 4};
        System.out.print("调用方法之前: ");
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i] + " ");
        }
        change(arr);
        System.out.print("\n调用方法之后: ");
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i] + " ");
        }
    }

    public static void change(int[] array) {
        array = new int[] {11,22,33,44};
    }
}

如果是引用传递,那么我在新方法中无论如何修改,那么都应该是影响原对象才对,而刚才我稍微调整了代码之后就发现其并非引用传递,而是值传递,这是因为当传递数组时,其传递的是"引用副本",而非真正的引用对象(也就是其本身)。

也就说,当传递数组时,其实传递的是"引用副本", 还是值传递

相关推荐
青云交7 分钟前
Java 大视界 -- Java 大数据在智能安防入侵检测系统中的多源数据融合与误报率降低策略(369)
java·大数据·入侵检测·智能安防·多源数据融合·误报率降低·视频语义理解
望获linux14 分钟前
【Linux基础知识系列】第六十四篇 - 了解Linux的硬件架构
linux·运维·服务器·开发语言·数据库·操作系统·嵌入式软件
我会冲击波19 分钟前
告别手写注释!变量命名、注释IDEA插件更新了,AI帮你搞定一切代码注释
java·intellij idea
BUG创建者30 分钟前
openlayer根据不同的状态显示不同的图层颜色
android·java·javascript
羊锦磊1 小时前
[java 常用类API] 新手小白的编程字典
java
都叫我大帅哥1 小时前
TOGAF技术架构阶段全解析:从理论到Java实战,避坑指南附赠!
java
星辰大海的精灵1 小时前
深入解析 CopyOnWriteArrayList
java·后端·算法
都叫我大帅哥1 小时前
Java ScopedValue:线程安全的"数据气泡"指南
java
Code季风1 小时前
深入 Spring IoC 容器:六大关键应用场景助力项目开发
java·spring
这些不会的1 小时前
iphone手机使用charles代理,chls.pro/ssl 后回车 提示浏览器打不开该网页
java