是通过引用传递对象到构造函数传递

use*_*361 5 java constructor scope

假设我有一个类和构造函数调用TestClass.

public class TestClass {
    Foo foo;

    public TestClass(Foo foo) {
        this.foo = foo; 
    }
}
Run Code Online (Sandbox Code Playgroud)

这里,构造函数接受一个对象,该对象是类的实例Foo.假设我static void main(String[] args)做了以下事情,与任何事情完全分开TestClass;

  • (1)实例化 foo

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

  • (3)改变内部状态 foo

在步骤(3),将foo 我的情况下TestClass 有它的状态变化?

ars*_*jii 14

不是通过引用传递的.相反,它是通过引用的传递的,这是一个微妙但重要的区别.

在您foomain()方法的其余部分进行变异后,该foo字段也会显示这些突变,因为您声明这两个变量都指向同一个实例.但是,如果您重新分配 foo新内容,foo则不会更改该字段.如果foo通过引用真正传递,那就不是真的.简而言之,Java中的所有内容都是通过值传递的; 恰好通过引用处理对象,因此传递这些引用的值.

我将尝试用一个例子来说明这一点.考虑以下课程:

class A {
    public int n;

    public A(int n) {
        this.n = n;
    }
}
Run Code Online (Sandbox Code Playgroud)

以及以下方法:

public static void mutate(A a) {
    a.n = 42;
}
Run Code Online (Sandbox Code Playgroud)

现在我们可以这样:

A a = new A(0);
A.mutate(a);

System.out.println(a.n);
Run Code Online (Sandbox Code Playgroud)
42

我们可以看到状态a发生了变化mutate().现在让我们修改静态方法:

public static void mutate(A a) {
    a = new A(42);
}
Run Code Online (Sandbox Code Playgroud)

然后再试一次:

A a = new A(0);
A.mutate(a);

System.out.println(a.n);
Run Code Online (Sandbox Code Playgroud)
0

如你所见,状态a没有变化.如果引用已传递给函数,我们可以预期重新分配的效果超出了方法的范围.然而,实际上已经传递了一些参考,因为改变参数也引起了方法之外的变化.