为什么构造函数在Java中通过引用传递?

时间:2013-07-13 09:08:52

标签: java

在java中,所有方法都是按值传递的。但是今天我了解到构造函数是通过引用传递的。

// Attack the internals of a Period instance
Date start = new Date();
Date end = new Date();
Period p = new Period(start, end);
end.setYear(78);  // Modifies internals of p!

这样可以编辑私人字段。

这个决定的原因是什么?或者我错过了什么?

5 个答案:

答案 0 :(得分:8)

你错了:

  

在java中,所有方法都按值传递。

相反:在Java中,所有参数都按值传递,甚至引用也按值传递。

您不“传递对象”,只引用对象。方法和构造函数也是如此。

所以

end.setYear(78);  // Modifies internals of p!

不会更改引用,只会更改引用所指向的对象。

答案 1 :(得分:3)

对于其他方法,它将以相同的方式工作。实际上,引用是按值传递的。

Class A{
   B b;
   void setB(B b) {
       this.b = b;
   }
};

A a;
B b;
A.setB(b);

b.change(); //changed in A

这意味着引用是按值传递的吗?

void f(A a) {
    a.change(); // caller will see that object is changed. We change it using reference
    a = new A(); // we change the value of refernce. No changes are visible outside the function
    a.change(); //new object is changing. No changes are visible outside the function
}

基本上你只是按值传递对象(整数)的地址。一切都是整数。你的类包含整数。它并没有改变。该地址上的对象确实如此。

答案 2 :(得分:1)

构造函数和方法的机制相同。来自doc

  

也会传入参考数据类型参数,例如对象   方法的价值。这意味着当方法返回时,   传入引用仍引用与以前相同的对象。   但是,可以在中更改对象字段的值   方法,如果他们有适当的访问级别

答案 3 :(得分:1)

不,您没有更改任何私人字段。未触及Period中的私有字段,它们仍引用相同的对象。不幸的是,Date对象是可变的。所以你通过Period对象看到了突变。

如果你想避免这种情况,请复制构造函数中传递的每个对象,只有这样你才能拥有自己的Date对象,而Period之外的任何人都无法修改。

答案 4 :(得分:0)

您只处理引用,而不是对象。

按值传递的经典定义。

引用变量的值是Java中的“地址”。将引用变量传递给方法时,会在堆栈上放置一个新的引用变量,并使用传递的引用变量值的副本来初始化新的本地引用变量值,就像任何基本类型一样。

注意:虽然您可以将引用视为内存地址,但事实并非如此。基本机制使其在逻辑上起作用,就好像它一样。

SHORT VERSION :引用是简单变量,就像其他基本类型一样,用于将参数传递给方法。一旦通过你可以做些什么显然是不同的。