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

Java方法调用修改对象疑问:为何自定义对象可改而Integer不行?

为什么Java中Integer对象无法被方法修改,但自定义对象可以?

这是Java里最容易混淆的参数传递问题之一,我来一步步帮你理清楚:

首先先看你给出的示例代码:

// My Integer Object
class MyInteger {
    Integer val;
}

// Change Java Object
public void test1() {
    Integer intval; // Integer object
    intval = 123;
    setInteger(intval); // THIS DOESN'T WORK
    TTY.putR("Integer Object=" + intval);
}

// Change My Object
public void test2() {
    MyInteger myInt; // MyInteger object
    myInt = new MyInteger();
    myInt.val = 456;
    setMyInteger(myInt); // THIS WORKS!
    TTY.putR("MyIntegerObject=" + myInt.val);
}

// Set an Integer object
public void setInteger(Integer val) {
    val = 888;
}

// Set a MyInteger object
public void setMyInteger(MyInteger myint) {
    myint.val = 999;
}

核心误区:Java是值传递,不是引用传递

很多人会误以为Java传递对象是“引用传递”,但准确来说,Java的所有参数传递都是值传递——当你传递对象时,传递的是「对象引用的副本」,而不是引用本身,更不是对象本身。这是理解这个问题的关键。

为什么test1里的Integer没被修改?

  • 当你调用setInteger(intval)时,intval指向的是值为123的Integer对象,方法会把这个引用的副本传给参数val。此时,intval和val是两个独立的引用,但都指向同一个123的Integer对象。
  • 然后你执行val = 888;——这里要注意:Integer是不可变类,它的内部值一旦创建就不能被修改。这句代码其实是创建了一个新的、值为888的Integer对象,然后让方法里的val引用指向这个新对象。
  • 但原引用intval还是指向原来的123对象,方法结束后,副本val被销毁,外部完全看不到这个变化,所以打印出来还是123。

为什么test2里的MyInteger能被修改?

  • 调用setMyInteger(myInt)时,同样传递的是myInt引用的副本,这个副本和原引用myInt都指向同一个MyInteger对象(里面的val是456)。
  • 执行myint.val = 999;时,你并没有修改引用本身,而是修改了引用指向的对象的内部属性。因为原引用和副本指向的是同一个对象,所以外部的myInt.val自然会看到这个修改后的结果。

总结一下

  • 如果你的方法只是修改参数引用本身(让它指向新对象),那么外部的原引用不会受到任何影响——因为你改的是副本。
  • 如果你的方法修改的是引用指向的对象的内部状态,并且这个对象是可变的(比如你的MyInteger),那么外部会看到变化——因为原引用和副本都指向同一个对象。
  • 像Integer、String这类不可变类,你根本无法修改它们的内部状态,所有看似“修改”的操作都是生成新对象,所以永远无法通过方法改变原引用指向的对象。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 09:03:36