2017-03-25 34 views
-2

首先,這不是重複問題。繼續閱讀,你會知道爲什麼。爲什麼交換功能失敗? (通過值vs通過vs參考)

答案here也是維基的一部分,詳細解釋了參數是如何在方法參數中傳遞的。我將在這裏複製/粘貼它,以便讀者不必前後移動一個新的瀏覽器標籤:

我覺得像「通過引用與傳值」爭論不是 超級有用。

如果你說「Java是通過任何(參考/值)」,但在 這兩種情況下你都沒有提供完整的答案。這裏有一些 額外的信息,有望幫助理解 發生在內存中。

在我們開始Java實現之前,堆棧/堆的崩潰過程: 值以一種很好的有序方式上下堆疊,就像在自助餐廳的板堆棧 一樣。在堆中的內存(也稱爲動態內存)是雜亂無章的。 JVM只需找到空間 ,然後將其釋放,因爲使用該變量的變量不再需要 。

好的。首先,本地原語進入堆棧。所以這個代碼:

int x = 3; 
float y = 101.1f; 
boolean amIAwesome = true; 

結果在此:

primitives on the stack

在聲明和實例化一個對象。實際的對象是 堆。什麼是堆棧?該堆上的對象地址在 堆上。 C++程序員會把它稱爲一個指針,但是一些Java開發者對「指針」這個詞是種族歧視。隨你。只知道 對象的地址進入堆棧。

像這樣:

int problems = 99; 
String name = "Jay-Z"; 

a b*7ch aint one!

數組是一個對象,如此這般在堆上爲好。那麼數組中的對象呢?他們得到自己的堆空間,並且每個對象的地址都在數組內。

JButton[] marxBros = new JButton[3]; 
marxBros[0] = new JButton("Groucho"); 
marxBros[1] = new JButton("Zeppo"); 
marxBros[2] = new JButton("Harpo"); 

marx brothers

那麼,是什麼得到,當你調用一個方法傳入?如果你通過一個 對象,你實際傳入的是對象的地址。有些人可能會說這個地址的「價值」,有些人說這只是一個 對這個物體的引用。這是 「參考」與「價值」支持者之間的聖戰的起源。你稱之爲 並不重要,因爲你知道傳入的內容是該對象的 地址。

private static void shout(String name){ 
    System.out.println("There goes " + name + "!"); 
} 

public static void main(String[] args){ 
    String hisName = "John J. Jingleheimerschmitz"; 
    String myName = hisName; 
    shout(myName); 
} 

一個串被創建和用於它的空間在堆上分配,並且 地址的字符串被存儲在堆棧上並給予 標識符hisName,由於第二字符串的地址是 與第一個相同,不會創建新的字符串,也不會分配新的堆空間,但會在堆棧上創建新的標識符。然後我們調用 shout():創建一個新的堆棧幀,並創建一個新的標識符name 並分配已存在的字符串的地址。

la da di da da da da

所以,價值,參考?你說「土豆」。

因此,根據相同的邏輯,交換功能也應該工作。但事實並非如此。讓我告訴你:

... main(Str..) { 
String one = "one"; 
String two = "two"; 
swap (one,two); 
System.out.println("outside method " + one); 
System.out.println("outside method " + two); 
} 

swap(String o, String t) { 
    String temp = o; 
      o = t; 
      t = temp; 
    System.out.println("inside method " + o); 
    System.out.println("inside method " + t); 
} 

這不會改變的變量onetwo值。爲什麼不?第二個問題:我們如何在(swap)方法中更改onetwo的值?

這是怎麼會看在內存:

enter image description here

+0

你用現有的答案粘貼了一個完整的其他問題,整個事情都很平常googleble。這是一個可怕的問題,你應該刪除它.. – pvg

+1

我讀過,我仍然認爲它是重複的。如果你認爲不是這樣,你需要解釋你自己的思考過程,說明你爲什麼不同意或理解鏈接問題的答案。 「所以,根據同樣的邏輯,交換功能也應該起作用。」不,這意味着你不理解你粘貼的解釋。公平地說,這是一個相當複雜的解釋,用不同尋常的術語。 –

+0

「我們如何在(交換)方法中更改一個和兩個值?」你不能。在Java中編寫交換方法是不可能的。 –

回答

1

swap不起作用,因爲Java通過值傳遞方法參數,而不是通過引用。這不是「聖戰」;這種說法只能由不瞭解事實的人提出。事實上,傳引用和傳值是客觀可證實的事實現象。您的swap示例是Java不能通過引用傳遞的規範證明。你所引用的文章中所有多餘的措辭都是冒煙的。

請記住,Java調用「引用」實際上是一個指針。即使在支持傳遞引用的C++中,指針通常也是按值傳遞的。你必須明確要求他們通過引用傳遞。

Java不會給你那個選項。你只能通過價值傳遞。

0

您的交換()方法將不會有幾個原因的工作。 調用swap()時,參數是對值 的新引用,所以當我在運行時調用swap(String1,String2)時,變量String1將被傳遞給參數中的新引用。

因此,儘管我們稱爲交換(1,2),但參數是範圍內的新變量,它們分別對應原始值&兩個值。

這意味着當我調用swap()時,參數是變量的副本,而不是相同的變量。由於字符串是不可變的,不能改變(只有變量被重新分配),這意味着即使我調用one = "SomethingElse",這意味着引用的參數副本等於SomethingElse,而不是原始變量,它的值仍然爲one = "something"我不重新分配one的原始參考,只是重新分配碰巧指向相同值的參數變量。

要解決這個問題,您需要在原始語句中執行您的方法代碼,而無需調用方法,這樣變量就是您希望的那樣。