# Java - Call by value <-> Call by reference



## mrbela (14. Mai 2012)

Hey Leute,

über google bin ich auf folgenden Link -der den Titel dieses Threads hier behandelt- aus diesem Forum hier gestoplert:

http://www.java-forum.org/allgemeines/4904-call-value-call-reference.html

Das stimmt doch nicht was da steht oder? Er meint zwar noch, dass im Internet fälschlicherweise oft steht, dass Java bei Objekten call of reference benutzt, macht aber ein Besiepiel, wo es offensichtlich ist, dass ein call of refernce genutzt wird.

Hier mein Beispiel zu call by value (primitiven Datentypen) und call by referende (bei Objekten):


```
package call_by;

import java.util.Vector;

public class Foo {
	
	private static void inkrement(int i) {
		i++;
		System.out.println("inkrement(i): " + i);
	}
	
	private static void inkrement(Vector<Integer> v) {
		v.add(new Integer(666));
	}

	public static void main(String[] args) {
		
		int i = 666;
		System.out.println("main() - i:" + i);
		inkrement(i);
		System.out.println("main() - i: " + i);
		
		Vector<Integer> v_int = new Vector<Integer>();
		v_int.add(new Integer(1));
		v_int.add(new Integer(2));
		
		System.out.println("--- Vector vor dem Aufruf von inkrement(vector)");
		int counter = 0;
		for (Integer integer : v_int) {
			System.out.println("vector[" + counter + "]: " + integer.intValue());
			counter++;
		}
		
		System.out.println("--- Aufruf von inkrement(vector)");
		inkrement(v_int);
		
		System.out.println("--- Vector nach dem Aufruf von inkrement(vector)");
		counter = 0;
		for (Integer integer : v_int) {
			System.out.println("vector[" + counter + "]: " + integer.intValue());
			counter++;
		}
	}
}
```

Ausgabe:

```
main() - i:666
inkrement(i): 667
main() - i: 666
--- Vector vor dem Aufruf von inkrement(vector)
vector[0]: 1
vector[1]: 2
--- Aufruf von inkrement(vector)
--- Vector nach dem Aufruf von inkrement(vector)
vector[0]: 1
vector[1]: 2
vector[2]: 666
```

Es ist doch wohl offensichtlich, dass Java bei dem Vector call of reference benutzt, wohingegen bei dem primitiven Datentyp (int) ein call by value benutzt wird.

Wie denkt Ihr darüber?


----------



## maki (14. Mai 2012)

> Wie denkt Ihr darüber?


Es gibt in Java kein CallByReference, nur & ausschliessslich CallByValue.
Das in Java Referenzen Werte sind die man kopieren kann wird gerne übersehen 

Ansonsten hatten wir das Thema schon sehr ausführlich im Forum, einfach mal suchen.


----------



## pl4gu33 (14. Mai 2012)

Wie schon in dem Thread von bygones zitiert ist hier der Abschnitt wichtig:


```
call by value
The caller cannot change the caller's reference variables, but it can change the fields in the caller's objects they point to.
```

dazu das von maki: 



maki hat gesagt.:


> Das in Java Referenzen Werte sind die man kopieren kann wird gerne übersehen



in deinem Beispiel geht es z.b. auch nicht den Vektor einfach zu ändern:


```
private static void inkrement(Vector<Integer> v) {    	
        v.add(new Integer(666));
        v=null;
    }
```

so z.b. das hat keine Wirkung auf den Vector da nur die Kopie in der Funktion geändert wird und die diese nicht zurück gegeben wird tada


----------



## mrbela (14. Mai 2012)

Okay, erstmal danke für die Posts!

Aber verstehen tue ich gerade nur Bahnhof!



> call by value
> The caller cannot change the caller's reference variables, but it can change the fields in the caller's objects they point to.



heißt genau?

Es wird zwar ein call of value durchgeführt, auch wenn man die Methode mit einer Refernz aufruft. Aber die Felder in diesem Objekt können vom Caller geändert werden?

Warum kann ich denn ein Element dem Vector hinzufügen, aber v=null geht nicht.

Das ist doch ein misch masch aus call by value und call by reference.

Ich verstehs grad voll nicht, sorry.


----------



## HimBromBeere (14. Mai 2012)

> aber v=null


Weil das eben das *Neureferenzieren* der Variable wäre, was aber eben bei call by value nicht geht.
Wenn Mario sein Aussehen verändert (Änderung der Eigenschaft), heißt er immer noch Mario (Referenz bleibt erhalten).


----------



## mrbela (14. Mai 2012)

Okay, verstehe.

Aber so eine richtige Kopie (wie bei den primitiven Datentypen) wird ja dennoch nicht erstellt, da ich ja ein Element dem Vector hnzufügen kann.

Also ist es doch nciht ganz streng ein call by value, oder?? Denn hier wird ja der übergebene Parameter wirklich nur kopiert. D.h. wenn ich dan dort was ändere, hat das auf das Objekt (in meinem Fall in der main-Funktion) keinen Einfluss mehr?!


----------



## Final_Striker (14. Mai 2012)

mrbela hat gesagt.:


> Aber so eine richtige Kopie (wie bei den primitiven Datentypen) wird ja dennoch nicht erstellt, da ich ja ein Element dem Vector hnzufügen kann.



Die Referenz wird kopiert, aber die beiden Referenzen referenzieren danach immer noch das gleiche Objekt. Deswegen kannst du über die kopierte Referenz dem Verktor Werte hinzufügen.


----------



## AngryDeveloper (14. Mai 2012)

In Java ist es wie bei den Pointern (*) in C. Erst C++ hat wirklich ein Call by Reference (&).
Es wird eben nicht der Wert (oder das ganze Objekt) der Variable kopiert, sondern eine Kopie deren Adresse übergeben.

C-Programmierung: Zeiger ? Wikibooks, Sammlung freier Lehr-, Sach- und Fachbücher


----------



## Gast2 (14. Mai 2012)

Doch es wird eine Kopie erstellt, eine Kopie der Referenz auf das Objekt. Diese Kopie wird dann an die Methode übergeben. Beide Referenzen (Original und Kopie) zeigen auf das SELBE Objekt, deswegen kannst du über die Kopie das Objekt verändern, du kannst aber die Originalreferenz nicht neureferenzieren.


----------



## fastjack (14. Mai 2012)

pl4gu33 hat gesagt.:


> in deinem Beispiel geht es z.b. auch nicht den Vektor einfach zu ändern:
> 
> 
> ```
> ...



Falsch! Nur v=null geht nicht


----------



## mrbela (14. Mai 2012)

Ahhhhh, jetzt wirds mir klar!!! Vielen, vielen Dank!!!

Also es erfolgt ein call by value, da eine Kopie erstellt wird. Diese Kopie zeigt aber auf das gleiche Objekt wie das Original.

Schreibt man in der Methode aber sowas wie v = new Vector<Integer>(); dann wird das v ja neu referenziert, und kann somit das Original, mit dem die Methode aufgerufen wurde nicht mehr ändern. Dies geht nur so lang, die Kopie nicht neu referenziert wird.

So müsste es stimmen!?!?

Vielen Dank für die Hilfe, wirklich!


----------



## Gast2 (14. Mai 2012)

Ja, kann man so sagen


----------



## pl4gu33 (14. Mai 2012)

fastjack hat gesagt.:


> Falsch! Nur v=null geht nicht



das war ja auch nur auf die "Änderung" von v bezogen, die ich der Methode hinzugefügt habe, dass das Int hinzufügen klappt war ja von vorne herein klar, darum kam ja erst die Frage auf warum das geht


----------



## Tomate_Salat (14. Mai 2012)

mrbela hat gesagt.:


> Also es erfolgt ein call by value, da eine Kopie erstellt wird.



Vorsicht, es wird keine Kopie erstellt. Beispiel:

```
MyObject myObject=new MyObject();
// ...
doSomethingWithMyObject(myObject);
```

Hier würde keine Kopie von [c]myObject[/c] übergeben werden, sondern lediglich die Speicheradresse (also der Ort, wo sich das Objekt befindet). D.h. die Methode [c]doSomethingWithMyObject[/c] bekommt als Information mitgeteilt, wo sich mein Objekt im Speicher befindet.

Willl man jetzt mit Methoden oder Felder dieses Objektes arbeiten, dann muss man es derefernzieren. Dazu nutzt man den [c].[/c].
Folgendes beispiel derefenziert das Objekt und ruft die Methode toString darauf auf:

```
public void doSomethingWithMyObject(MyObject myo) {
    myo.toString();
    //...
}
```


----------



## Gast2 (14. Mai 2012)

Das wurde ja oben auch schon erklärt dass eine Kopie der Referenz erzeugt wird


----------



## Tomate_Salat (14. Mai 2012)

Hörte sich für mcih so an, als ob der TO noch von einer Kopie des Objektes ausgehen würde. Sollte ich mich irren, kann er meinen Post gerne ignorieren .


----------



## fastjack (14. Mai 2012)

pl4gu33 hat gesagt.:


> dass das Int hinzufügen klappt war ja von vorne herein klar, darum kam ja erst die Frage auf warum das geht



hat sich aber anders gelesen. Zumindest war dann v.add(...) etwas verwirrend gemeint.


----------

