java中所有参数传递都是值传递:基本类型传数值副本,引用类型传地址副本;修改形参变量不影响实参,但通过引用修改对象状态会影响原对象。

Java 中所有参数传递都是值传递,包括对象引用。所谓“值传递”,是指传递的是变量的副本:基本类型传的是数值副本,引用类型传的是引用地址的副本。因此修改形参本身(如重新赋值)不会影响实参,但通过引用修改对象内部状态(如 set 字段、add 元素)会影响原对象。
验证基本类型参数传递
编写测试用例时,用 int、String(不可变,但可体现值传递语义)、boolean 等典型基本类型或其包装类,观察方法内修改是否影响外部变量。
示例代码:
public class PassByValueTest {
public static void changeInt(int x) {
x = 100; // 修改形参 x,不影响调用处的原始变量
}
@Test
public void testBasicTypePassByValue() {
int a = 42;
changeInt(a);
assertEquals(42, a); // ✅ 仍为 42,证明是值传递
}
}
验证对象引用类型参数传递
重点区分「修改引用本身」和「修改引用指向的对象内容」。前者不生效,后者生效——这正是值传递(传引用地址副本)的直接体现。
测试建议包含两部分:
- 修改引用(如 obj = new Person("new")),验证原引用不变
- 修改对象状态(如 obj.setName("updated")),验证原对象被改变
public class Person {
private String name;
public Person(String name) { this.name = name; }
public void setName(String name) { this.name = name; }
public String getName() { return name; }
}
@Test
public void testObjectReferencePassByValue() {
Person p = new Person("Alice");
// 场景1:在方法内重新赋值引用(不改变原引用)
reassignReference(p);
assertEquals("Alice", p.getName()); // ✅ 仍是 Alice
// 场景2:在方法内修改对象属性
modifyObjectState(p);
assertEquals("Bob", p.getName()); // ✅ 已变为 Bob
}
private void reassignReference(Person p) {
p = new Person("Charlie"); // 只改变了形参 p 的指向,不影响外部 p
}
private void modifyObjectState(Person p) {
p.setName("Bob"); // 修改堆中对象的状态,外部可见
}
验证数组和集合的传递行为
数组和 ArrayList 等属于引用类型,同样遵循值传递规则:传的是数组引用/集合引用的副本。
关键点:
- arr = new int[]{...} 或 list = new ArrayList() → 不影响外部数组/集合
- arr[0] = 99 或 list.add(...) → 影响外部数组/集合内容
测试示例:
@Test
public void testArrayAndListPassByValue() {
int[] arr = {1, 2, 3};
List<string> list = new ArrayList(Arrays.asList("a", "b"));
reassignArray(arr);
reassignList(list);
assertEquals(1, arr[0]); // ✅ 未变
assertEquals("a", list.get(0)); // ✅ 未变
modifyArrayContent(arr);
modifyListContent(list);
assertEquals(99, arr[0]); // ✅ 已变
assertTrue(list.contains("c")); // ✅ 已添加
}
private void reassignArray(int[] arr) { arr = new int[]{9, 8, 7}; }
private void reassignList(List<string> list) { list = new ArrayList(); }
private void modifyArrayContent(int[] arr) { arr[0] = 99; }
private void modifyListContent(List<string> list) { list.add("c"); }
</string></string></string>
使用断言与日志辅助验证
在关键位置打印对象的 System.identityHashCode(),可直观确认是否为同一对象实例(即是否指向堆中同一地址)。
例如:
Person p = new Person("X");
System.out.println(System.identityHashCode(p)); // 记录原始 hash
modifyObjectState(p);
System.out.println(System.identityHashCode(p)); // hash 不变 → 同一对象
配合 JUnit 的 assertEquals、assertNotSame、assertSame 等断言,能更严谨验证传递行为。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











