2013-07-31 29 views
9

我想出了我的代碼中的一個問題。第一代碼:Java for循環按值或引用

public class Main { 

    /** 
    * @param args 
    */ 
    public static void main(String[] args) { 
     String[] blablubb = { "a", "b", "c" }; 

     for(String s : blablubb) { 
      s = "over"; 
     } 
     printArray(blablubb); 


     for (int i = 0; i < blablubb.length; i++) { 
      blablubb[i] = "over"; 
     } 
     printArray(blablubb); 

    } 

    public static void printArray(String[] arr) { 
     for(String s : arr) { 
      System.out.println(s); 
     } 
    } 

} 

的輸出是:

a 
b 
c 
over 
over 
over 

我假定第一回路也將覆蓋在陣列中的字符串。所以在任何情況下輸出都會結束。它似乎創建了一個值的副本,而不是創建一個引用。 我從未感覺到這一點。我做錯了嗎?是否有選項可以創建參考?

//編輯: 似乎每個人都知道,除了我。我來自C背景,並沒有足夠重視與C非常不同的術語參考。 幸運的是,我花了10分鐘才弄明白這一點(這一次)。

+3

HTTP ://stackoverflow.com/questions/40480/is-java-pass-by-reference – assylias

回答

16

此:

for (String s : blablubb) { 
    s = "over"; 
} 

等於這樣的:

for (int i = 0; i < blablubb.length; i++) { 
    String s = blablubb[i]; 
    s = "over"; 
} 

這將創建與數組值的副本的臨時字符串,你只改變副本。這就是爲什麼blablubb[]內容保持不變。

如果你想改變數值數組中,只需用你的第二個選項:

for (int i = 0; i < blablubb.length; i++) {   
    blablubb[i] = "over"; 
} 

而且,順便說一句,你可以打印帶有一行的數組:

System.out.println(Arrays.toString(blablubb)); 
1

for-each循環不會修改它迭代的對象集合中包含的對象。它通過的價值不是參考。

0
s = "over"; 

只是改變了s的引用而不是數組中的字符串。

blablubb[i] = "over"; 

改變存儲在第i個位置的數組中的值

4

for(String s : blablubb)循環等同於下面的代碼:

for(int i = 0; i < blablubb.length; i++) { 
    String s = blablubb[i]; 
    s = "over"; 
} 

希望,從這裏就可以看出,所有的你正在做正在重新分配與s不同的值而不更改blablubb[i]。這解釋了你看到的輸出。

0
for(String s : StringArray) 
{ 
} 

就像

for(int i = 0; i < StringArray.length; i++) 
{ 
    String s = StringArray[i]; 
} 
0

當你想要做一個低級別的優化,知道怎麼了,你要看看Java代碼內,裏面的字節碼是(編譯的代碼)

for(String s : blablubb) { 
      s = "over"; 
} 

是等於有:

for (int i = 0; i < blablubb.length; i++) { 
    String s = blablubb[i];    
    s = "over"; 
} 

,這就是爲什麼輸出是如何。