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 只有值传递,对象传递的是引用地址的值!

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

相关推荐
伍树明6 小时前
本地搭建搜索Agent(SpringAI + RAG + SearXNG + MCP)
java·spring·agent·mcp
怎么面试6 小时前
EasyExcel 基础用法
java·服务器
huaiqiongying6 小时前
Springboot3+SpringSecurity6Oauth2+vue3前后端分离认证授权-客户端
java·vue.js·spring boot
华仔啊6 小时前
Java异常处理别再瞎搞了!阿里大神总结的 9 种最佳实践,让你的代码更健壮!
java·后端
杨杨杨大侠6 小时前
手搓责任链框架 5:执行流程
java·spring·github
Metaphor6927 小时前
Java 压缩 PDF 文件大小:告别臃肿,提升效率!
java·经验分享·pdf
m0_709788627 小时前
单片机点灯
java·前端·数据库
野犬寒鸦7 小时前
力扣hot100:螺旋矩阵(边界压缩,方向模拟)(54)
java·数据结构·算法·leetcode
初始化7 小时前
JavaFx:生成布局 ViewBinding,告别 @FXML 注解
java·kotlin