You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java仅按值传递,为何List/对象经方法修改后值会变化?

为什么Java按值传递时,修改List的方法会影响原List?

嘿,这个问题绝对是Java新手最容易踩的坑之一,我来给你把逻辑理清楚~

首先要明确一个核心点:Java确实只支持按值传递,但这里的「值」要分情况看:

  • 对于基本数据类型(比如int、boolean),传递的是变量实际值的副本;
  • 对于引用数据类型(比如List、自定义对象),传递的是对象引用地址的副本——划重点,是地址的副本,不是对象本身的副本!

结合你的代码来拆解:

  1. 在main方法里,List<Integer> list = new ArrayList<>()创建了一个ArrayList对象存放在堆内存中,而变量list其实只是存了这个对象在堆里的内存地址。
  2. 当你调用addExternally(list)时,Java会把list里存的这个地址复制一份,传给方法参数里的list变量——这时候方法里的list和main里的list是两个不同的变量,但它们指向的是同一个堆内存里的ArrayList对象。
  3. 所以在addExternally里调用list.add(11)、list.add(12),本质是通过这个复制过来的地址,找到堆里的那个ArrayList对象,修改的是对象本身的内容。main里的list变量依然指向这个对象,自然能看到修改后的结果。

那什么时候修改方法里的参数不会影响原对象?举个例子,如果你的addExternally方法是这样的:

private static void addExternally(List<Integer> list) {
    // 重新给参数list赋值,让它指向一个新的ArrayList对象
    list = new ArrayList<>();
    list.add(11);
    list.add(12);
}

这时候方法里的list变量已经指向了新的对象,和main里的list没有关系了,原List自然不会有任何变化——因为你修改的是参数变量本身的引用,不是对象的内部状态。

简单总结:Java的按值传递,传递的是「变量存储的内容」的副本。对于引用类型,变量存的是对象地址,所以传递的是地址副本,方法里通过地址操作同一个对象,就会影响原变量指向的对象;但如果是改变参数变量的指向(让它指向新对象),原变量不受影响。

内容的提问来源于stack exchange,提问作者pradeep

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 08:30:27