2013-07-31 12 views
9

Znalazłem problem w moim Kodeksie. Pierwszy kod:Java dla pętli według wartości lub przez odniesienie

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); 
     } 
    } 

} 

Wyjście jest:

a 
b 
c 
over 
over 
over 

Przypuszczałem pierwsza pętla będzie także zastąpić ciąg w tablicy. W każdym razie wyjście będzie zakończone. Wygląda na to, że tworzy kopię wartości zamiast tworzyć odniesienie. Nigdy tego nie zauważyłem. Czy robię to źle? Czy istnieje możliwość utworzenia odwołania?

// Edycja: Wygląda na to, że wszyscy wiedzą o tym oprócz mnie. Jestem z pochodzenia w tle i nie zwracam wystarczającej uwagi na termin referencyjny, który jest bardzo odmienny od C. Na szczęście zajęło mi to tylko 10 minut, aby to zrozumieć (tym razem).

+3

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

Odpowiedz

16

to:

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

jest równa:

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

ta tworzy tymczasowy String odpis wartości z tablicy i zmienić tylko kopię. Dlatego treść blablubb[] pozostaje nietknięta.

Jeśli chcesz zmienić wartości w tablicy, wystarczy użyć drugą opcję:

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

I, nawiasem mówiąc, można wydrukować tablicę z tylko jedną linię:

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

Obie pętle nie modyfikują obiektów zawartych w zbiorze obiektów, nad którymi iteruje. Przekazuje wartość, a nie referencję.

0
s = "over"; 

po prostu zmienia odniesienie s, a nie ciąg w tablicy.

blablubb[i] = "over"; 

zmienia wartość przechowywaną w miejscu ith w tablicy

4

Twój for(String s : blablubb) pętla jest równoznaczne z następującym kodem:

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

Mamy nadzieję, że z tego widać, że wszystko robisz ponownie przypisuje inną wartość do s bez zmiany blablubb[i]. To wyjaśnia wynik, który widzisz.

0
for(String s : StringArray) 
{ 
} 

jest jak

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

Gdy chcesz zrobić optymalizację niskim poziomie, know-how, trzeba zajrzeć do kodu Java i wewnątrz bajtowego kodu albo (kod skompilowany)

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

jest równa z:

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

i dlatego wynik jest taki, jaki jest.