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

Java参数是pass by value还是pass by reference?两段代码结果为何不同

Java参数传递机制差异原因解析

首先明确核心规则:
Java 只有按值传递机制:

  • 如果参数是基本类型,传递的是基本类型的字面量值的拷贝
  • 如果参数是引用类型,传递的是引用所指向的对象在堆中的内存地址的拷贝,不是原引用变量本身,也不是对象本身

第一段Integer参数代码的逻辑说明

class Runner{
    public static void main(String[] args)
    {
        Integer test = new Integer(20);
        updateObject(test);
        System.out.println(test);
    }
    public static void updateObject(Integer test)
    {
        test = 50;
    }
}

输出为20的原因:

  1. Integer是不可变类,它内部存储数值的value字段被final修饰,没有对外提供修改值的方法,任何修改Integer的操作实际都是创建新的Integer对象。
  2. updateObject方法的参数test是main方法中test引用的地址拷贝,是方法内的局部变量。当执行test = 50时,会触发自动装箱,等价于test = Integer.valueOf(50),这一步是把方法内的局部test引用指向了新创建的数值为50的Integer对象,完全没有修改main方法中原test引用的指向,也没有修改原Integer对象的能力。
  3. 方法执行结束后,局部变量销毁,main方法中的test还是指向原来数值为20的Integer对象,所以输出20。

第二段自定义类参数代码的逻辑说明

import java.util.*;
class Test {
    int num;
    Test(int x){
        num = x;
    }
    Test(){
        num = 0;
    }
}

class Runner{
    public static void main(String[] args)
    {
        Test test = new Test(20);
        updateObject(test);
        System.out.println(test.num);
    }
    public static void updateObject(Test test)
    {
        test.num = 50;
    }
}

输出为50的原因:

  1. updateObject方法的参数test同样是main方法中test引用的地址拷贝,两个引用指向堆内存中的同一个Test对象。
  2. 方法内执行test.num = 50时,并没有修改局部test引用的指向,而是顺着地址找到共同指向的Test对象,直接修改了它内部的公共属性num。
  3. 方法执行结束后,main方法中的test还是指向这个被修改了属性的Test对象,所以访问num属性得到的是修改后的50。

核心差异总结

  • 第一段代码的操作是修改方法内局部引用的指向,让它指向新对象,不会对原引用和原对象产生任何影响
  • 第二段代码的操作是通过局部引用访问共同指向的对象,修改对象的内部属性,原引用指向的还是这个对象,自然能看到修改结果

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 22:06:03