在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!
这样可以编辑私人字段。
这个决定的原因是什么?或者我错过了什么?
答案 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 :引用是简单变量,就像其他基本类型一样,用于将参数传递给方法。一旦通过你可以做些什么显然是不同的。