请注意为什么用作方法参数的原语会在对象按原样使用时复制其值?
答案 0 :(得分:6)
在Java中,所有参数都是按值传递的 - 但是对于引用类型(即除了基元之外的所有内容),变量的值不是对象本身 - 它是引用对象。因此,引用被复制到方法的参数中,因此它引用同一个对象。
请注意,这不仅适用于方法调用:
StringBuilder x = new StringBuilder();
StringBuilder y = x; // Copy the value of x, which is a *reference*
y.append("Hello");
System.out.println(x); // Prints "Hello"
这里,x
和y
引用相同的对象,即使它们是单独的变量。因此,当通过append
变量通过y
调用更改该对象的内容时,也会通过x
变量显示更改。
我认为这有点像给某人你家的地址:如果我给两个人我的家庭住址,其中一个把门涂成红色,那么当第二个人到家时,他们会看到红门也是。我不给他们自己的房子,我给他们一个到我家的方式。
有许多关于此的文章 - 尽管不幸的是,有些人会声明通过Java引用传递对象。他们不是 - 正如我上面所说,参考文献是按价值传递的。 Scott Stanchfield有good article about this等等。
答案 1 :(得分:1)
为了扩展Jon Skeet所说的内容,原始类型通常非常小 - 双倍是8个字节。另一方面,对象可能是巨大的,因此传递对它们的引用可以节省时间和堆栈空间,而不是复制整个对象。另外,这允许您修改对象的内容。
答案 2 :(得分:1)
这就是它的样子但不是。 Java总是按值传递。
当你宣布这样的事情时:
Date aDate = new Date();
变量aDate
实际上不是对象,而是对象引用。当您将该对象引用传递给另一个方法时,将传递该引用的“副本”(就像使用基元一样传递值的副本)
现在,由于这两个副本“引用”相同的底层对象,您会看到在其中一个上发送消息会影响另一个,但如果更改引用以指定新的引用,则另一个不会更改。
例如:
class Some {
int data = 0;
}
class Other {
void doSomething( Some o ) {
o.data = 10;
}
void change( Some a ) {
a = new Some();
a.data = 1024;
}
}
class Main {
public static void main( String [] args ) {
// create an object and get its object reference
Some original = new Some();
System.out.println( original.data ); // prints 0
// now pass it to a method from the class "Other"
Other o = new Other();
other.doSomething( original );
System.out.println( original.data ); // prints 10, because data was changed in "doSomething"
// To probe that the reference is not passed, but a copy of it
// invoke the "change" method.
other.change( original );
System.out.println( original.data ); // remains 10, instead of 1024.
// the value 1024 was changed in the new reference, and the one passed along
// didn't change. It still refers to the original object.
}
}
我希望这会有所帮助