![](/img/trans.png)
[英]Java Statics Primitives, Objects, Methods and the Heap (Memory Management & Best Practices)
[英]Objects and primitives in methods
請提出意見,為什么當原樣使用對象時,被用作方法參數的原語會復制其值?
在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
指的是同一對象,即使它們是單獨的變量也是如此。 因此,當通過y
變量通過append
調用更改該對象的內容時,該更改也通過x
變量可見。
我認為這有點像給某人您的住所地址:如果我給兩個人我的住所地址,其中一個人將門塗成紅色,那么當第二個人訪問房子時,他們會看到紅色門也。 我不是給他們自己的房子,而是給他們一種進入我家的方法。
關於此的文章很多,盡管不幸的是有些文章聲稱對象是通過Java引用傳遞的。 它們不是-引用是按值傳遞的,正如我上面所說的。 Scott Stanchfield在許多其他方面對此都有很好的文章 。
為了進一步解釋Jon Skeet所說的內容,原始類型通常非常小-兩倍為8字節。 另一方面,對象可以是巨大的,因此與復制整個對象相比,將引用傳遞給它們可以節省時間和堆棧空間。 另外,這允許您修改對象的內容。
那就是它的樣子,但事實並非如此。 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.
}
}
我希望這有幫助
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.