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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 17:38:47  来源:igfitidea点击:

Is passing object to constructor pass by reference

javaconstructorscope

提问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 footo TestClassconstructor

  • (3) Change the internal state of foo

  • (1) 实例化 foo

  • (2) 将实例传递fooTestClass构造函数

  • (3) 改变内部状态 foo

After step (3), will the foowithinmy instance of TestClassalsohave 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 fooin the rest of your main()method, the foofield will also exhibit these mutations, as you state, since both variables point to the same instance. However, if you reassignfooto something new, the foofield will not be changed. This would not be true if foowere 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.

在您foomain()方法的其余部分进行变异之后,该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 awas 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 ais 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

enter image description hereYes, because you are assigning same object to another reference of Foo class, i.e. object is same, but being referred by two reference.

在此处输入图片说明是的,因为您将相同的对象分配给 Foo 类的另一个引用,即对象是相同的,但被两个引用引用。