Java 通过引用将对象传递给构造函数
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/19485434/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Is passing object to constructor pass by reference
提问by user2763361
Suppose I have a class and constructor called TestClass
.
假设我有一个名为TestClass
.
public class TestClass {
Foo foo;
public TestClass(Foo foo) {
this.foo = foo;
}
}
Here, the constructor accepts an object which is an instance of class Foo
. Suppose my static void main(String[] args)
does the following, completely separate from any TestClass
;
在这里,构造函数接受一个对象,它是 class 的一个实例Foo
。假设 mystatic void main(String[] args)
执行以下操作,与 any 完全分开TestClass
;
(1) Instantiate
foo
(2) Pass instance
foo
toTestClass
constructor(3) Change the internal state of
foo
(1) 实例化
foo
(2) 将实例传递
foo
给TestClass
构造函数(3) 改变内部状态
foo
After step (3), will the foo
withinmy instance of TestClass
alsohave its state changed?
步骤(3)后,将foo
内我的情况下TestClass
也有它的状态变化?
采纳答案by arshajii
It is notpassed by reference. Rather, it is passed by valueof the reference, which is a subtle but important distinction.
它不是通过引用传递的。相反,它是通过引用的值传递的,这是一个微妙但重要的区别。
After you mutate foo
in the rest of your main()
method, the foo
field will also exhibit these mutations, as you state, since both variables point to the same instance. However, if you reassignfoo
to something new, the foo
field will not be changed. This would not be true if foo
were truly passed by reference. In short, everything is passed by value in Java; it just so happens that objects are dealt with by reference, and so the values of these references are passed.
在您foo
对main()
方法的其余部分进行变异之后,该foo
字段也将展示这些变异,正如您所说,因为两个变量都指向同一个实例。但是,如果您重新分配foo
给新内容,则该foo
字段不会更改。如果foo
真正通过引用传递,则情况并非如此。简而言之,Java 中的一切都是按值传递的;碰巧对象是通过引用处理的,因此这些引用的值被传递。
I'll try to illustrate this with an example. Consider the following class:
我将尝试用一个例子来说明这一点。考虑以下类:
class A {
public int n;
public A(int n) {
this.n = n;
}
}
and the following method:
以及以下方法:
public static void mutate(A a) {
a.n = 42;
}
Now we can have something like this:
现在我们可以有这样的事情:
A a = new A(0);
A.mutate(a);
System.out.println(a.n);
42
We can see that the state of a
was changed in mutate()
. Now let's modify the static method:
我们可以看到 的状态在a
中发生了变化mutate()
。现在让我们修改静态方法:
public static void mutate(A a) {
a = new A(42);
}
and try again:
然后再试一次:
A a = new A(0);
A.mutate(a);
System.out.println(a.n);
0
As you can see, the state of a
is unchanged. If the reference had been passed to the function, we would expect the effect of the reassignment to be evident beyond the scope of the method. Nevertheless, somereference was in fact passed, since mutating the argument caused changes outside of the method as well.
如您所见,状态a
不变。如果引用已传递给函数,我们希望重新分配的效果在方法范围之外是明显的。然而,实际上传递了一些引用,因为改变参数也会导致方法之外的更改。
回答by MadProgrammer
After step (3), will the foo within my instance of TestClass also have its state changed?
在步骤 (3) 之后,我的 TestClass 实例中的 foo 是否也会改变其状态?
Yes.
是的。
You might like to take a read through this
你可能想通过采取读此
Updated...
更新...
Now, assuming you pass the constructor a primitive value...
现在,假设您向构造函数传递了一个原始值...
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);
}
This will output...
这将输出...
myFoo = 3
yourFoo = 1
Which demonstrates the fact that changing the value of a primitive does not change the value maintained by the constructor/method.
这表明更改原语的值不会更改构造函数/方法维护的值。
Equally, if you change the object reference after you pass it
同样,如果您在传递对象引用后更改它
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()));
}
Will output
会输出
myFoo == yourFoo = false
As the object references are not the same.
由于对象引用不一样。
回答by Batty
Yes, because you are assigning same object to another reference of Foo class, i.e. object is same, but being referred by two reference.
是的,因为您将相同的对象分配给 Foo 类的另一个引用,即对象是相同的,但被两个引用引用。