假设我有一个名为TestClass
的类和构造函数。
public class TestClass {
Foo foo;
public TestClass(Foo foo) {
this.foo = foo;
}
}
这里,构造函数接受一个对象,该对象是类Foo
的一个实例。假设我的static void main(String[] args)
执行以下操作,与任何TestClass
完全分开;
(1)实例化foo
(2)将实例foo
传递给TestClass
构造函数
(3)更改foo
在第(3)步之后,<{1}} 我的<{1}} 的实例中的foo
是否会更改其状态?
答案 0 :(得分:14)
不通过引用传递。相反,它是通过引用的 value 传递的,这是一个微妙但重要的区别。
在您foo
方法的其余部分中变异main()
后,foo
字段也会显示这些突变,因为您声明这两个变量都指向同一个实例。但是,如果您重新分配 foo
新内容,则不会更改foo
字段。如果通过引用真正传递了foo
,则情况并非如此。简而言之,Java中的所有内容都是通过值传递的;恰好通过引用处理对象,因此传递这些引用的值。
我将尝试用一个例子来说明这一点。考虑以下课程:
class A {
public int n;
public A(int n) {
this.n = n;
}
}
和以下方法:
public static void mutate(A a) {
a.n = 42;
}
现在我们可以这样:
A a = new A(0);
A.mutate(a);
System.out.println(a.n);
42
我们可以看到a
中mutate()
的状态已更改。现在让我们修改静态方法:
public static void mutate(A a) {
a = new A(42);
}
再试一次:
A a = new A(0);
A.mutate(a);
System.out.println(a.n);
0
如您所见,a
的状态未发生变化。如果引用已经传递给函数,我们可以预期重新分配的效果超出了方法的范围。然而,实际上传递了一些引用,因为改变参数也导致了方法之外的更改。
答案 1 :(得分:3)
是的,因为你将同一个对象分配给另一个Foo类的引用,即object是相同的,但被两个引用引用。
答案 2 :(得分:0)
在步骤(3)之后,我的TestClass实例中的foo也会有 它的状态改变了吗?
是
您可能想要阅读this
<强>更新... 强>
现在,假设您将构造函数传递给原始值...
public class TestClass {
int foo;
public TestClass(int foo) {
this.foo = foo;
}
public String toString() {
return "TestClass: " + foo;
}
}
public static void main(String args[]) {
int myFoo = 1;
TestClass test = new TestClass(myFoo);
myFoo += 2;
System.out.println("myFoo = " + myFoo);
System.out.println("yourFoo = " + test);
}
这将输出......
myFoo = 3
yourFoo = 1
这表明更改基元的值不会改变构造函数/方法维护的值。
同样,如果在传递后更改对象引用
public class TestClass {
Foo foo;
public TestClass(Foo foo) {
this.foo = foo;
}
public Foo getFoo() {
return foo;
}
}
public static void main(String args[]) {
Foo myFoo = new Foo();
TestClass test = new TestClass(myFoo);
myFoo = new Foo();
System.out.println("myFoo == yourFoo = " + myFoo.equals(test.getFoo()));
}
将输出
myFoo == yourFoo = false
由于对象引用不相同。