不可变且按值传递
Posted
技术标签:
【中文标题】不可变且按值传递【英文标题】:Immutable and pass by value 【发布时间】:2012-01-05 15:26:08 【问题描述】:我有以下代码 一个可变的 Person 类、String 和一个修改 String 和 Person 实例的方法
class Person
int a = 8;
public int getA()
return a;
public void setA(int a)
this.a = a;
@Override
public String toString()
return "Person [a=" + a + "]";
--
public class TestMutable
public static void main(String[] args)
Person p = new Person();
p.setA(34);
String s = "bar";
modifyObject(s, p); //Call to modify objects
System.out.println(s);
System.out.println(p);
private static void modifyObject(String str, Person p)
str = "foo";
p.setA(45);
输出符合预期。它打印
bar
Person [a=45]
现在,我的问题是
你说 str="foo" 的地方发生了什么?
首先我们假设 s='bar' 并且数据驻留在 0x100 内存中
现在字符串的引用被传递给另一个方法,另一个方法尝试使用 s="foo" 将内存位置 (0x100) 的内容更改为 'foo'。这是正在发生的事情,还是“foo”是在不同的内存位置创建的?
java 是否按值传递引用?
【问题讨论】:
可能重复:***.com/questions/40480/is-java-pass-by-reference 【参考方案1】:在modifyObject
中,当您分配给str
时,您并没有改变str
,而是将其设置为指向不同的对象。由于是按值传递的,所以你的modifyObject
方法本地的str
指针是main
中s
指针的副本,所以当你更改前者时,它不会影响以后的文件。
另一方面,当涉及到p
时,modifyObject
中的那个仍然是main
中那个的副本,但是两个指针都指向内存中的同一个对象,因此如果你调用一个来自modifyObject
的方法,你实际上是在改变p
指向的东西。
【讨论】:
【参考方案2】:Java 总是按值而不是按引用传递参数。
让我通过example 解释一下:
public class Main
public static void main(String[] args)
Foo f = new Foo("f");
changeReference(f); // It won't change the reference!
modifyReference(f); // It will change the object that the reference variable "f" refers to!
public static void changeReference(Foo a)
Foo b = new Foo("b");
a = b;
public static void modifyReference(Foo c)
c.setAttribute("c");
我将分步骤解释:
1- 声明一个名为 f
类型为 Foo
的引用,并将其分配给一个类型为 Foo
的新对象,其属性为 "f"
。
Foo f = new Foo("f");
2- 在方法方面,声明了一个名为 a
的类型为 Foo
的引用,并且它最初分配给 null
。
public static void changeReference(Foo a)
3- 当您调用方法changeReference
时,引用a
将被分配给作为参数传递的对象。
changeReference(f);
4- 声明一个名为 b
类型为 Foo
的引用,并将其分配给一个类型为 Foo
的新对象,其属性为 "b"
。
Foo b = new Foo("b");
5- a = b
正在将引用 a
NOT f
重新分配给其属性为 "b"
的对象。
6- 当您调用modifyReference(Foo c)
方法时,会创建一个引用c
并将其分配给具有"f"
属性的对象。
7-c.setAttribute("c");
会改变引用c
指向它的对象的属性,和引用f
指向它的对象是同一个对象。
我希望您现在了解在 Java 中如何将对象作为参数传递:)
【讨论】:
哇!让我们把它剪下来写一本书吧:-) 解释得很好!【参考方案3】:在这个函数中调用“modifyObject(s, p);”您正在将变量 s 的值发送到 modifyObject 方法的局部变量 str。因此创建了一个新变量,它的值发生了变化,但原始变量保持不变。
【讨论】:
【参考方案4】:有时人们在通过引用传递时会感到困惑。可以更改引用所指的对象(给人一种传递引用的印象),但不能修改引用本身。所以它仍然是按值传递。
【讨论】:
以上是关于不可变且按值传递的主要内容,如果未能解决你的问题,请参考以下文章