在下面的代码中,我假设两个对象都引用了同一个对象,但是下面的例子说我错了。对不起,如果它是重复的。
class A {
public String a;
public void set(String a) {
this.a = a;
}
}
class B {
public String b;
public void set(String b) {
this.b = b;
}
}
A aC = new A();
B bC = new B();
String str = "aaa";
aC.set(str);
bC.set(aC.a);
aC.a += "a";
System.out.println(aC.a);
System.out.println(bC.b);
答案 0 :(得分:3)
Java是按值传递的。引用按值传递。
aC.a += "a"
创建一个新的String对象,这就是为什么它没有反映在bC中。
从字面上看,你说的是
aC.a = aC.a + "a"
因此,您可以将=
符号解释为aC.a
映射到新的String对象,该对象是aC.a
和"a"
的串联。但是当您更改aC.a
的引用时,您并未更改bC.b
的引用,因此它将指向相同的旧字符串。
答案 1 :(得分:3)
你认为是什么让你感到困惑
aC.a += "a";
修改aC.a
引用的String对象的状态。事实并非如此。字符串是不可变的,上面的代码行创建一个新的String对象并将其分配给aC.a,保留原始对象的所有其他引用。
使用StringBuilder
进行相同的测试,并致电
aC.a.append("a");
你会得到不同的结果。
答案 2 :(得分:3)
Java规范说Java中的所有内容都是按值传递的。 Java中没有“pass-by-reference”这样的东西。
理解这一点的关键是像
这样的东西Dog myDog;
不是狗;它实际上是指向狗的指针。
这意味着,当你有
时Dog myDog = new Dog("Rover");
foo(myDog);
你实际上是将创建的Dog对象的地址传递给foo方法。
(我说基本上b / c Java指针不是直接地址,但最容易以这种方式来考虑它们)
假设Dog对象驻留在内存地址42.这意味着我们将42传递给方法。
如果方法被定义为
public void foo(Dog someDog) {
someDog.setName("Max"); // AAA
someDog = new Dog("Fifi"); // BBB
someDog.setName("Rowlf"); // CCC
}
让我们来看看发生了什么。
现在让我们考虑一下方法之外会发生什么:
myDog改变了吗?
有钥匙。
记住myDog是指针,而不是真正的Dog,答案是否定的。 myDog的值仍为42;它仍然指向原来的狗。
跟随地址并改变其末尾的内容是完全有效的;但是,这不会改变变量。
Java的工作方式与C完全相同。您可以指定指针,将指针传递给方法,按照方法中的指针操作并更改指向的数据。但是,您无法更改指针指向的位置。
答案 3 :(得分:1)
JVM中有三个字符串对象。 “aaa”,“a”和“aaaa”(因为字符串是不可变的)。 最初,aC.a和bC.b指向相同的字符串对象“aaa”。在这一行aC.a + =“a”;代码正在改变aC.a的引用以指向“aaaa”。 所以现在aC.a - > “aaaa”和bC.b - > “AAA”。 我希望我很清楚。
答案 4 :(得分:0)
Java实际上是按引用值传递的。将复制实际引用,并将该副本发送到函数。