我编写了以下程序来测试equals和Java pass by value功能(根据文档Java是按值传递),所以当我将对象a
传递给方法时,我实际上传递了堆值。如果我在方法中更改对象的引用是什么?会发生什么?
package equalstest;
public class EqualsMethodTest {
public static void main(String[] args) {
EqualsMethodTest a = new EqualsMethodTest();
EqualsMethodTest b = new EqualsMethodTest();
System.out.println(" Comparing a and B");
System.out.println(a == b);
System.out.println(a.equals(b));
EqualsMethodTest c = compare(a, b);
System.out.println(" Comparing B and C after interchanging references");
System.out.println(b == c);
System.out.println(b.equals(c));
System.out.println(" Comparing A and C after interchanging references");
System.out.println(a == c);
System.out.println(a.equals(c));
}
static EqualsMethodTest compare(EqualsMethodTest a, EqualsMethodTest b) {
EqualsMethodTest c = a;
a = b;
return c;
}
}
我的输出低于输出:
比较a和B
在改变之前a == b false
在改变之前a.equals b false
交换引用后比较B和C
改变后b == c false
改变之后b.equals c false
交换引用后比较A和C
改变后a == c真实 改变后a.equals c true
compare
实际发生了什么? c
时,它是否指向a
的内存位置?b
分配给a
时会发生什么?答案 0 :(得分:2)
当我创建一个新的引用时,它是否指向一个?
的内存位置
是的,因为您实际上并未创建c
(使用 new ),您只需将c指向a。
将b分配给?
时会发生什么
此处也是如此,从现在开始,您的a
指向b
。因此,最后你的c也指向a
,指向b
到a
。
答案 1 :(得分:1)
引用可以指向新对象或任何现有对象。
EqualsMethodTest a = new EqualsMethodTest();
// Reference--^ ^--- new object
因此,当您执行EqualsMethodTest c = a;
时,表示c
将指向a
指向的对象。所以基本上在这个时间点c
和a
两个引用都指向同一个对象。同样地,它发生在a = b;
。
通过价值混淆
Java 引用按值传递。
答案 2 :(得分:1)
调用Java“按值传递”虽然在技术上是正确的,但却非常令人困惑。 Java是按值传递的,但传递的值是引用。那么你的方法会发生以下情况:
EqualsMethodTest c = a;
新变量c
的值等于参数a
的值。因此,c
现在是与a
相同的对象的引用。a = b;
变量a
的值等于b
的值。因此a
和b
现在引用同一个对象。return c;
返回c
的值,该值是a
最初指向的对象的引用。因为Java是按值传递的,所以调用compare
的代码没有任何变化。所以,如果你打电话
`compare(a,b);`
变量a
和b
仍然指向与之前相同的对象; compare
方法的第二行所做的更改是方法的本地。
答案 3 :(得分:0)
每次声明EqualsMethodTest时,实际上都是在创建指向它的指针。 所以在你的compare()函数中,你创建了一个新指针c,它指向与a相同的位置。然后你告诉指针a指向位置b。
在更改之前,您指针指向值a,指针b指向值b。在更改之后,指针c指向值a,指针a指向值b,指针b指向值b。