Call by value (Java): Unterschied zwischen den Versionen

Aus Byte-Welt Wiki
Zur Navigation springenZur Suche springen
K
K (Call by Reference)
Zeile 19: Zeile 19:
 
<syntaxhighlight lang="java">public static void main(String[] args) {
 
<syntaxhighlight lang="java">public static void main(String[] args) {
 
   List<String> l1 = new ArrayList<>();
 
   List<String> l1 = new ArrayList<>();
   // hier wird nun das Objekt übergeben, das geändert wird
+
   // hier wird nun eine Referenz auf das Objekt übergeben, das geändert wird
 
   doSomething(l1);
 
   doSomething(l1);
 
   // Ausgabe: [doSomething]
 
   // Ausgabe: [doSomething]

Version vom 8. März 2018, 16:26 Uhr

Call by value und Call by reference

Diese beiden Begriffe stiften oft Verwirrung. Es wird oft davon geredet, dass Java bei den primitiven Datentypen wie int "call by value" verwendet, bei Objekten "call by reference"

Call by value

public static void main(String[] args) {
   int x = 5;
   // die variable x wird kopiert und somit nicht durch die methode verändert
   doSomething(x);
   // immer noch 5
   System.out.println(x);
}

public static void doSomething(int x) {
   x = x+1;
}

Call by Reference

public static void main(String[] args) {
   List<String> l1 = new ArrayList<>();
   // hier wird nun eine Referenz auf das Objekt übergeben, das geändert wird
   doSomething(l1);
   // Ausgabe: [doSomething]
   System.out.println(l1);
}

public static void doSomething(List<String> l) {
   l.add("doSomething");
}

Obwohl viele zu dem zweiten Bsp. "Call by Reference" sagen ist das falsch!

Java kennt kein "Call by Reference"!

Dies erkennt man, wenn man die genaue Definitionen der beiden Aussagen betrachtet:

call by value

When you call a method, the method sees a copy of any primitives past to it.
Thus any changes it makes to those values have no effect on the caller's variables.
This also applies to references passed as parameters. 
The caller cannot change the caller's reference variables, but it can change the fields in the caller's objects they point to.

call by reference

When you call a method by reference, the callee sees the caller's original variables passed as parameters, not copies. 
References to the callee's objects are treated the same way. 
Thus any changes the callee makes to the caller's variables affect the caller's original variables. 
Java never uses call by reference. It always uses call by value.

Die Programmiersprache C++ kennt "Call by reference":

#include <iostream.h>
void swap(int &a,int &b)
{
   int tmp=a;
   a=b;
   b=tmp;
};

void main()
{
   int a=1;
   int b=2;
   swap(a,b);
   cout<<"a: "<<a<<endl;
   cout<<"b: "<<b<<endl;
};

Hier werden explizit die Referenzen übergeben und geändert!

In Java sähe es dann so aus:

public static void main(String[] args){
   Integer i = Integer.valueOf(1);
   Integer j = Integer.valueOf(2);
   System.out.println(i + " " + j);
   swap(i,j);
   System.out.println(i + " " + j);
}
	
public static void swap(Integer i, Integer j) {
   Integer tmp = i;
   i = j;
   j = tmp;
}

Die Ausgabe ist aber beides mal

1 2

oder ein C Beispiel

void testr (char **query) {
    (*query)++;
}

Nimmt man z.b. die Zeichenkette "Hallo" - wenn man nun davon ausgeht, dass die Referenz vorher auf das 'H' zeigte, zeigt sie nun nach dem Aufruf auf das 'a' in der Zeichenkette. D.h. hier wird nicht der Inhalt der Referenz geändert, sondern die Refernz selber ( = call by reference)

-- bygones 07.06.2004