Call by value (Java)

Aus Byte-Welt Wiki
Zur Navigation springenZur Suche springen

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

<code=java>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;

}</code=java>

Call by Reference

<code=java>public static void main(String[] args) { ArrayList l1 = new ArrayList();

               // hier wird nun das Objekt übergeben, das geändert wird

doSomething(l1);

               // Ausgabe: [doSomething]

System.out.println(l1); } public static void doSomething(ArrayList l) { l.add("doSomething"); }</code=java>

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 <code=ini>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.</code=ini>

call by reference <code=ini>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.</code=ini>

Die Programmiersprache C++ kennt "Call by reference": <code=cpp>#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;

};</code=cpp>

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

In Java sähe es dann so aus: <code=java>public static void main(String[] args){ Integer i = new Integer(1); Integer j = new Integer(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; }</code=java>

Die Ausgabe ist aber beides mal <code=ini>1 2</code=ini>

oder ein C Beispiel <code=c>void testr (char **query) {

   (*query)++;

} </code=c>

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