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

为何Java数组在不同操作下参数传递表现截然不同?

Java数组参数传递:替换对象与修改元素的表现差异解析

在Java中操作数组时,两种不同的参数传递行为容易让人困惑:

场景1:替换数组对象

代码1:

import java.util.Arrays;

public static void main(String[] args) {
    String[] fruits = {"apple", "banana", "cabbage"};
    replaceArray(fruits);
    System.out.println(Arrays.toString(fruits));
}

public static void replaceArray(String[] array){
    String[] animals = {"dog", "cat", "pig"};
    array = animals;
    System.out.println(Arrays.toString(array)); 
}

输出1:

[dog, cat, pig]
[apple, banana, cabbage]

方法内将数组变量指向新数组后,方法内输出新数组,但main方法中原数组并未改变。

场景2:修改数组元素

代码2:

import java.util.Arrays;

public static void main(String[] args) {
    String[] fruits = {"apple", "banana", "cabbage"};
    replaceArray(fruits);   
    System.out.println(Arrays.toString(fruits));
}

public static void replaceArray(String[] array){
    array[0] = "cat";
    array[1] = "dog";
    array[2] = "pig";
    System.out.println(Arrays.toString(array));
}

输出2:

[cat, dog, pig]
[cat, dog, pig]

直接修改数组元素时,main方法中的原数组也同步被修改,看似是按引用传递。

核心疑问:为何同是数组操作,替换数组对象与修改数组元素的参数传递表现截然不同?


核心本质:Java始终是按值传递

Java的参数传递规则只有一种:按值传递——方法接收的是实际参数的副本,而非参数本身。对于数组(属于对象类型)来说,传递的是数组对象引用的副本,这是理解两种差异的关键。

对场景1的解析

  • main方法中的fruits是一个引用,指向内存中存储{"apple", "banana", "cabbage"}的数组对象。
  • 调用replaceArray(fruits)时,会复制一份fruits的引用,赋值给方法参数array——此时array和fruits指向同一个数组对象。
  • 当执行array = animals时,只是把方法内的array这个引用副本,重新指向了新的{"dog", "cat", "pig"}数组对象。但main方法中的fruits引用完全不受影响,仍然指向原来的数组,所以最终输出原数组内容。

对场景2的解析

  • 同样,调用replaceArray(fruits)时,array是fruits引用的副本,二者指向同一个数组对象。
  • 执行array[0] = "cat"这类操作时,是通过array这个引用副本,找到它指向的数组对象,修改对象内部的元素值。因为fruits和array指向同一个数组对象,所以main方法中通过fruits访问数组时,能看到修改后的结果。

可以用通俗类比理解:把引用看作写着数组地址的纸条。场景1是复制了一张纸条,然后把复制的纸条改成写新地址,原纸条的地址不变;场景2是拿着复制的纸条找到对应的房间,修改房间里的东西,原纸条指向的还是这个房间,所以进去能看到变化。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 11:26:15