2014-07-04 5 views
12

Ich weiß, dass Java ist immer pass-by-Wert, aber ich verstehe nicht, warum dies funktioniert:Parameter in Java vorbei

public static void swap(int[] arr, int i, int j) 
{ 
    int tmp = arr[i]; 
    arr[i] = arr[j]; 
    arr[j] = tmp; 
} 
public static void main(String[] args) 
{ 
    int[] arr = {3, 4, 5, 6}; 
    swap(arr, 1, 3); 
    // arr becomes {3, 6, 5, 4} 
} 

Und das funktioniert nicht:

public static void swap(int[] arr, int[] arr2) 
{ 
    int[] tmp = arr; 
    arr = arr2; 
    arr2 = tmp; 
} 
public static void main(String[] args) 
{ 
    int[] arr = {3, 4, 5, 6}; 
    int[] arr2 = {1, 2, 5, 6}; 
    swap(arr, arr2); 
} 

Warum?

+0

Sie müssen Referenzen verstehen. –

+1

mögliches Duplikat von [Ist Java "pass-by-reference" oder "pass-by-value"?] (Http://stackoverflow.com/questions/40480/is-java-pass-by-reference-or-pass -by-value) – vaxquis

+1

Java übergibt ** Referenzen ** nach Wert. –

Antwort

14

In dem zweiten Verfahren werden Sie versuchen, Referenzen zu tauschen, das wird nicht funktionieren, weil die Referenzen selbst Pass sind -von-Wert.

Die erste Methode funktioniert ordnungsgemäß, weil sie das Objekt ändert, auf das vom Array verwiesen wird (das veränderbar ist), es ändert nicht die Referenz selbst.

Weitere Informationen zu den Unterschieden zwischen Vorbeilauf und Vorbeilauf finden Sie unter this blog post.

+0

Ich würde auch hinzufügen, dass Arrays in Java veränderbar sind, deshalb funktioniert das erste Beispiel. –

7

Ihr erstes Beispiel ist die Übertragung der Werte im Array.

Die zweite Sie versuchen, die Referenz auszutauschen (Arrays sind Objekte in Java). Die Verweise sind lokale Kopien (pass-by-value) und haben keinen Einfluss auf den calee-Kontext.

(Frage # 56,903 über Call-by-Wert; Stack sollte sich öffnen PassByValue.com ;-)

+4

passbyvalue.com bereits vergeben. – PeterMmm

+0

Großartiger Namensvorschlag. :) Hat ähnliche Punch zu der Domain wie SO hat ... – progo

3

Wenn Sie jemals C oder C verwendet habe ++ und wissen, wie Zeiger funktionieren dann, was für mich dieses ganze Szenario tick gemacht ist die folgende Erklärung ab:

In Java, everything is passed by value. 
In case of Objects, the reference (pointer) is passed by value. 

Also im Grunde die Swap-Funktion von

public void swap(int[] a, int[] b) 
{ 
    etc. 
} 

Wird nur den Zeiger auf die a int [] -Array und den Zeiger auf die b int [] -Array bekommen. Sie tauschen nur zwei Zeiger aus. Sie können den Inhalt von Zeigern nicht ändern.

Grundsätzlich ist die C entspricht

void swap(int* a, int* b) 
{ 
    int* temp = a; 
    a = b; 
    b = temp; 
} 

int main(void) 
{ 
    int a[] = {5,6,7,8}; 
    int b[] = {1,2,3,4}; 
    swap(a,b); 
} 

Während auch in C, das nur etwa so funktionieren würde:

void swap(int** a, int** b) 
{ 
    int* temp = (*a); 
    (*a) = (*b); 
    (*b) = temp; 
} 

int main(void) 
{ 
    int a[] = {5,6,7,8}; 
    int b[] = {1,2,3,4}; 
    swap(&a, &b); 
} 

Natürlich können Sie nicht die Referenz eines Verweises in Java senden . Zeiger in diesem Sinne gibt es in Java nicht.

Um das Objekt in einer anderen Funktion tatsächlich zu ändern, benötigen Sie daher ein "Holder" -Objekt, auf das die Referenz kopiert wird, aber die darin enthaltene Referenz zu dem Objekt, das Sie ändern möchten, ist tatsächlich die tatsächliche Referenz von das Objekt, wenn das Sinn machte.

Und so würde die folgende Arbeiten:

public class ArrayHolder 
{ 
    public int[] array; 

    public ArrayHolder(int[] array) 
    { 
     this.array = array; 
    } 
} 

public void swap(ArrayHolder a, ArrayHolder b) 
{ 
    int[] temp = a.array; 
    a.array = b.array; 
    b.array = temp; 
} 

public static void main(String[] args) 
{ 
    ArrayHolder aaa = new ArrayHolder(new int[] {5,6,7,8}); 
    ArrayHolder bbb = new ArrayHolder(new int[] {1,2,3,4}); 
    swap(aaa,bbb); 
} 
1
  • Die erste Swap Sie die Daten des Arrays ändern.(referenziert von arr: eine Referenz) so ist es

  • Der zweite Austausch, ändern Sie arr, arr2, zwei lokale Variablen. so, wenn Sie das Verfahren zu beenden, werden die beiden neuen Variablen

1
  • Arr und arr2 lokale Variablen sind zerstört, so werden sie vernichtet werden, wenn die Swap-Verfahren zu beenden.
  • Außerhalb der Swap-Methode sind lokale Variablenänderungen nicht betroffen.