Java 方法传参,到底是值还是引用?

原文来自于:zha-ge.cn/java/26

Java 方法传参,到底是值还是引用?

面试中的困惑

那天在面试中,技术官问了一个看似简单的问题:"Java 方法传参是值传递还是引用传递?"

我自信满满地回答:"基本类型是值传递,对象是引用传递!"

面试官微笑着在白板上写下了这段代码:

java 复制代码
public void swap(Integer a, Integer b) {
    Integer temp = a;
    a = b;
    b = temp;
}

// 调用
Integer x = 10, y = 20;
swap(x, y);
System.out.println("x=" + x + ", y=" + y); // 结果是什么?

"你觉得 x 和 y 会交换吗?" 面试官问道。

我愣住了。按照我的理解,Integer 是对象,应该是引用传递,x 和 y 应该会交换才对!

真相:被"引用传递"误导

结果当然没变,输出是 x=10, y=20,根本没有交换!

这时我意识到,我对 Java 传参机制的理解有误。面试官接着展示了另一个例子:

java 复制代码
public void modifyList(List<String> list) {
    list.add("新元素");
    list = new ArrayList<>(); // 重新赋值
    list.add("这个不会影响原list");
}

List<String> myList = new ArrayList<>();
myList.add("原始元素");
modifyList(myList);
// myList 里有什么?

答案是 ["原始元素", "新元素"]。第二个赋值操作并没有影响到原来的 list!

Java 只有值传递

面试官解释说:Java 中永远只有值传递,没有引用传递!

理解"值"的关键在于:

  • 基本类型:传递的是数据本身的副本
  • 对象类型:传递的是引用地址的副本

用快递来比喻:

传参类型 比喻 实际情况
基本类型 给你一份文件的复印件 修改副本不影响原件
对象类型 给你一张地址纸条的复印件 通过地址能找到同一个房子,但换掉纸条不影响原地址

核心理解:引用的副本 ≠ 引用传递

看这段代码:

java 复制代码
public void testReference(StringBuilder sb) {
    sb.append("_modified"); // 能修改对象内容
    sb = new StringBuilder("new"); // 重新赋值不影响外部
}

StringBuilder original = new StringBuilder("hello");
testReference(original);
System.out.println(original); // 输出: hello_modified

为什么 append 有效而重新赋值无效?

因为方法接收的是引用地址的副本

  • 可以通过这个副本地址修改同一个对象
  • 但改变副本本身(重新赋值),不会影响原来的引用

经验总结

这次面试让我明白:

  1. 概念要精准:Java 没有 C++ 的引用传递,统一都是值传递
  2. 区分对象和引用:修改对象内容与改变引用指向效果不同
  3. 包装类的注意事项:Integer、String 等不可变对象,重新赋值不会影响原值

现在每当有人问起 Java 传参机制,我都会先讲这个 swap 的故事,然后强调:

Java 只有值传递,对象传递的是引用地址的值!

理解这一点后,很多困惑就迎刃而解了。你是否也曾被这个概念困扰过呢?

相关推荐
stu_kk4 分钟前
泛微Ecology9实现流程界面隐藏按钮
java·oa
czhc11400756634 分钟前
JAVA1027抽象类;抽象类继承
android·java·开发语言
练习时长一年12 分钟前
jdk动态代理的实现原理
java·开发语言
三无少女指南30 分钟前
关于JVM调优,我想聊聊数据和耐心
java·开发语言·jvm
好好研究36 分钟前
手动创建maven项目
java·maven
從南走到北1 小时前
JAVA国际版任务悬赏发布接单系统源码支持IOS+Android+H5
android·java·ios·微信·微信小程序·小程序
4Forsee1 小时前
【Android】View 事件分发机制与源码解析
android·java·前端
刘一说1 小时前
Spring Boot 主程序入口与启动流程深度解析:从 `@SpringBootApplication` 到应用就绪
java·spring boot·后端
eguid_12 小时前
【从零开始开发远程桌面连接控制工具】01-项目概述与架构设计
java·远程连接·远程控制·远程桌面·vnc·teamviewer
一 乐2 小时前
车辆管理|校园车辆信息|基于SprinBoot+vue的校园车辆管理系统(源码+数据库+文档)
java·前端·数据库·vue.js·论文·毕设·车辆管理