Java中在函数内修改对象是否需要返回才能更新对象值?
问题解答
首先直接给结论:你给出的示例代码里,foo1()方法中的foo对象状态会被修改,不需要特意把对象返回就能完成值的更新。
首先先纠正一个普遍的认知偏差:Java所有参数传递都是按值传递,不存在按引用传递的机制。方法接收到的对象参数,本质是原对象引用的一个副本,这个副本和外层方法的原引用,指向堆内存中完全相同的对象实例。
不同操作的效果差异
你可以对照两种常见的参数操作场景理解:
- 场景1:调用对象方法修改内部状态(即你的示例场景)
someFunction里拿到的foo参数,虽然是引用的副本,但和foo1()里定义的foo指向堆里同一个Foo实例。这时候调用foo.doSomething()修改对象内部属性、状态,本质是直接操作堆上的公共实例,等方法执行完回到foo1(),读到的自然是已经被修改后的对象状态,不需要返回对象就能生效。
对应你的示例代码逻辑:public void foo1() { Foo foo = new Foo(); someFunction(foo); // 此处foo的状态已经被doSomething()修改 } public void someFunction(Foo foo) { foo.doSomething(); // 操作的是和外层共享的堆内存Foo实例 } - 场景2:在方法内给参数变量重新赋值
如果你在someFunction里写foo = new Foo(),本质只是把方法内部持有的引用副本,指向了一个新创建的堆对象,这个操作完全不会影响外层foo1()里的原引用指向,外层的foo还是指向最开始创建的那个实例。这种情况下就算你把新对象返回,外层也要手动用变量接收才能拿到新对象,不接收的话外层原对象不会有任何变化。
打个通俗的比方:你把自己家钥匙配了一把给朋友,这个配的钥匙就是Java方法传参时传递的引用副本。朋友拿配的钥匙进你家,把你家的电视换了,等你拿自己原有的钥匙回家,肯定能看到新电视——这就是修改对象内部状态的场景。但如果朋友拿着配的钥匙,自己另外买了套房子,把配的钥匙磨了改成开他家门的,这和你家、你手里的原钥匙没有任何关系,你回家看到的还是自己原来的房子——这就是给参数重新赋值的场景。
内容的提问来源于stack exchange,提问作者Unprotesting
相关产品推荐
相关产品推荐

