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

时间:2013-10-21 02:37:19

标签: java constructor scope

假设我有一个名为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 是否会更改其状态?

3 个答案:

答案 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

我们可以看到amutate()的状态已更改。现在让我们修改静态方法:

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)

enter image description here是的,因为你将同一个对象分配给另一个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

由于对象引用不相同。