Call by value (Java): Unterschied zwischen den Versionen

Aus Byte-Welt Wiki
Zur Navigation springenZur Suche springen
(Die Seite wurde neu angelegt: „= ''Call by value'' und ''Call by reference'' = Diese beiden Begriffe stiften oft Verwirrung. Es wird oft davon geredet, dass Java bei den primitiven Datentypen …“)
 
K
 
(5 dazwischenliegende Versionen von 2 Benutzern werden nicht angezeigt)
Zeile 4: Zeile 4:
  
 
==Call by value==
 
==Call by value==
<code=java>public static void main(String[] args) {
+
<syntaxhighlight lang="java">public static void main(String[] args) {
 
   int x = 5;
 
   int x = 5;
 
   // die variable x wird kopiert und somit nicht durch die methode verändert
 
   // die variable x wird kopiert und somit nicht durch die methode verändert
Zeile 14: Zeile 14:
 
public static void doSomething(int x) {
 
public static void doSomething(int x) {
 
   x = x+1;
 
   x = x+1;
}</code=java>
+
}</syntaxhighlight>
  
 
==Call by Reference==
 
==Call by Reference==
<code=java>public static void main(String[] args) {
+
<syntaxhighlight lang="java">public static void main(String[] args) {
ArrayList 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]
System.out.println(l1);
+
  System.out.println(l1);
}
+
}
public static void doSomething(ArrayList l) {
+
 
l.add("doSomething");
+
public static void doSomething(List<String> l) {
}</code=java>
+
  l.add("doSomething");
 +
}</syntaxhighlight>
  
Obwohl viele zu dem zweiten Bsp "Call by Reference" sagen ist das [[falsch]]!
+
Obwohl viele zu dem zweiten Bsp. "Call by Reference" sagen, ist das '''<span style="color:red;">falsch</span>'''!
  
 
==Java kennt kein "Call by Reference"!==
 
==Java kennt kein "Call by Reference"!==
Zeile 35: Zeile 36:
  
 
'''call by value'''
 
'''call by value'''
<code=ini>When you call a method, the method sees a copy of any primitives past to it.
+
<syntaxhighlight lang="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.
 
Thus any changes it makes to those values have no effect on the caller's variables.
 
This also applies to references passed as parameters.  
 
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>
+
The caller cannot change the caller's reference variables, but it can change the fields in the caller's objects they point to.</syntaxhighlight>
  
 
'''call by reference'''
 
'''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.  
+
<syntaxhighlight lang="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.  
 
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.  
 
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>
+
Java never uses call by reference. It always uses call by value.</syntaxhighlight>
  
 
Die Programmiersprache C++ kennt "Call by reference":
 
Die Programmiersprache C++ kennt "Call by reference":
<code=cpp>#include <iostream.h>
+
<syntaxhighlight lang="cpp">#include <iostream.h>
 
void swap(int &a,int &b)
 
void swap(int &a,int &b)
 
{
 
{
Zeile 62: Zeile 63:
 
   cout<<"a: "<<a<<endl;
 
   cout<<"a: "<<a<<endl;
 
   cout<<"b: "<<b<<endl;
 
   cout<<"b: "<<b<<endl;
};</code=cpp>
+
};
 +
</syntaxhighlight>
  
Hier werden explizit die Referenzen übergeben und geändert !
+
Hier werden explizit die Referenzen übergeben und geändert!
  
 
In Java sähe es dann so aus:
 
In Java sähe es dann so aus:
<code=java>public static void main(String[] args){
+
<syntaxhighlight lang="java">public static void main(String[] args){
Integer i = new Integer(1);
+
  Integer i = Integer.valueOf(1);
Integer j = new Integer(2);
+
  Integer j = Integer.valueOf(2);
System.out.println(i + " " + j);
+
  System.out.println(i + " " + j);
swap(i,j);
+
  swap(i,j);
System.out.println(i + " " + j);
+
  System.out.println(i + " " + j);
}
+
}
 
 
public static void swap(Integer i, Integer j) {
+
public static void swap(Integer i, Integer j) {
Integer tmp = i;
+
  Integer tmp = i;
i = j;
+
  i = j;
j = tmp;
+
  j = tmp;
}</code=java>
+
}
 +
</syntaxhighlight>
  
 
Die Ausgabe ist aber beides mal
 
Die Ausgabe ist aber beides mal
<code=ini>1 2</code=ini>
+
<syntaxhighlight lang="ini">1 2</syntaxhighlight>
  
 
oder ein C Beispiel
 
oder ein C Beispiel
<code=c>void testr (char **query) {
+
<syntaxhighlight lang="c">void testr (char **query) {
 
     (*query)++;
 
     (*query)++;
 
}
 
}
</code=c>
+
</syntaxhighlight>
 +
 
 +
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)
 +
 
 +
--[[Benutzer:bygones | bygones]] 07.06.2004
  
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)
+
[[Kategorie:Java Grundlagen]]
 +
[[Kategorie:Programmierung Grundlagen]]

Aktuelle Version vom 28. März 2018, 08:35 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