# call by reference & value



## hos15 (23. Jul 2016)

Hallo Liebe Java Freunde, 
ich verstehe leider nicht den unterschied zwischen diesen beiden Begriffen. Ich habe mich im Internet umgeschaut und finde keine Erklärung wo es wirklich "Klick " macht und ich das selber 
an ein Beispiel sagen ob eine Methode als call by reference  oder value geschrieben ist. 

Ansicht kann ich diese Beiden worte " gut " erklären z.B : 
Florian hat ein Bild und möchte das an Sabine schicken. Wenn Florian das Bild Kopiert und an
Sabine schickt dann hat Sabine das gleiche Bild. Führt Sabine Veränderung an diesem Bild dann hat es keine Auswirkung auf Florians Bild. (Call by Value). Wenn Florian jedoch ein link an Sabine sendet wo das Bild zu sehen ist dann sind jegliche Veränderungen  die Sabine führt auch bei Florian zu sehen. (Call by reference) 
oder anders: 
Einfache Werte werden kopiert und Änderungen
an den lokalen Kopien haben keine weiteren Auswirkungen Call by Value). Bei komplexen
Werten wird eine Referenz übergeben, mittels derer die Methode auf die
Inhalt zugreifen und sie dauerhaft verändern kann.(Call by reference)

Aber leider kann ich das nicht auf Methoden umsetzen wenn mir 2 Methoden angezeigt werden kann ich nicht sagen ob das Cbv oder Cbr ist. 
z.B diese Methoden 


```
static int[] legeQuadrateAn( int l ) {
int[] feld = new int[l];
for( int i=0; i<l; i++ ) feld[i] = i*i;
return feld;
}
```


```
static void tausche( int[] feld, int i, int j ) {
int tmp = feld[i];
feld[i] = feld[j];

feld[j] = tmp;
}
```


----------



## mrBrown (23. Jul 2016)

In Java ists leicht:
primitive Datentype->CallByValue, Objekte->CallByRef

int wäre als CbV, int[] CbR


----------



## InfectedBytes (23. Jul 2016)

Erstmal, java macht *immer *call-by-value, es kann auch gar nichts anderes.
Java unterscheidet zwischen primitiven Typen (int, char, etc) und Referenztypen (Objekte). Die primitiven Typen beinhalten direkt ihren entsprechenden Wert. Referenztypen beinhalten eine Referenz, welche auf das konkrete Objekt im heap zeigt.
Wenn du nun einen primitiven Typen an eine Methode übergibst, so wird einfach der Wert kopiert.

```
void test(int i) { i = 5; }
// ...
int x = 42;
test(x);
System.out.println(x); // immernoch 42
```
Das gleiche gilt auch für Objekte, aber wie bereits oben erwähnt, ist eine Variable auf ein Objekt erstmal nur eine Referenz, d.h. es wird auch nur die Referenz kopiert:

```
void test(Point p) { p = new Point(1,1); }
// ...
Point point = new Point(42, 20);
test(point);
System.out.println(point.x); // immernoch 42
```
Eine neue zuweisung hat also keinerlei Auswirkung auf die "ursprüngliche" Variable, da es eben zwei Referenzen sind, welche halt nur auf das gleiche Objekt zeigten.

Allerdings kann man natürlich von beiden Referenzen aus das Objekt verändern:

```
void test(Point p) { p.x = 10; }
// ...
Point point = new Point(42, 20);
test(point);
System.out.println(point.x); // 10
```
Die Referenzen zeigen auf das gleiche Objekt und können es somit beide verändern.


----------



## hos15 (23. Jul 2016)

naja ich muss mir das mehrmals durchlesen ich hoffe ich werde es verstehen ..


----------



## 4a61766120617274697374 (23. Jul 2016)

call by reference:
Wenn du ein Objekt nach dem erstellen einem anderen Objekt übergibst und es dann dort verändert wird, dann ist das Objekt überall verändert wo es momentan existiert.

Bsp.:

```
String[] myArray = {"a", "b"};
  new VereandereArray(myArray); // call by reference
  System.out.println(myArray);  // {"a", "b", "neuer Inhalt"}
```

call by value:
Hier würde das Array "myArray" nicht verändert. In Java ist das aber nur mit primitiven Daten möglich. Hier also nicht möglich! Wenn man nicht das Originale Objekt verändern möchte, erstellt man eine Kopie davon und übergibt die Kopie.

Bsp.:

```
int myInt = 5;
  new VereandereMich(myInt); // call by value
  System.out.println(myInt); // bleibt 5 !!
```


----------



## InfectedBytes (23. Jul 2016)

nein, das ist *nicht *call-by-reference. In Java werden Parameter *immer *by value übergeben.
Dies siehst du eben an diesem einfachen Beispiel:

```
void f(int[] arr) {
  arr = {1,2,3};
}
// ...
int[] werte = {42};
f(werte);
System.out.println(Arrays.toString(werte));
```
Wenn Java wirklich by-reference arbeiten könnte, so würde nun das Array {1,2,3} ausgegeben werden, da die Referenz verändert werden konnte.
Beim Ausführen wird man aber feststellen, das weiterhin {42} ausgegeben, obwohl dem Parameter ein neuer Wert zugewiesen wurde. Dies liegt eben genau daran, dass Java die Parameter immer via call-by-value übergibt.

Parameter werden bei Java immer kopiert. Bei Objekten führt das dazu dass die Referenz auf das Objekt im Heap kopiert wird. Somit besitzen Caller und Callee jeweils eine eigene, unabhängige Referenz, welche bloß auf das gleiche Objekt im Heap zeigen. Klar, mit beiden Referenzen kann man dieses Objekt nun manipulieren, aber das _ändern _der _Referenz _selber, hat keine Auswirkungen auf die andere Referenz.


----------



## 4a61766120617274697374 (23. Jul 2016)

```
class ChangeArray
{
  public void add(String[] myArray) {
    myArray[1] = "new";
  }
}


public class Test
{
  public static void main(String[] args) {
    String[] myArray = new String[2];
    myArray[0] = "a";

    for (String tmp : myArray) {
      System.out.println(tmp);
    }

    ChangeArray changer = new ChangeArray();
    changer.add(myArray);

    System.out.println("---------------------------");
    for (String tmp : myArray) {
      System.out.println(tmp);
    }

//    output:
//    a
//    null
//    ---------------------------
//    a
//    new
  }
}
```


----------



## InfectedBytes (23. Jul 2016)

Dort wird das Objekt verändert, auf welches die *Referenz *_zeigt_, nicht aber die Referenz selber, denn diese ist nur eine *Kopie *der original Referenz. Objekte liegen bei Java immer im Heap und werden nur durch Referenzen angesprochen.
http://openbook.rheinwerk-verlag.de/javainsel9/javainsel_03_005.htm
http://stackoverflow.com/questions/40480/is-java-pass-by-reference-or-pass-by-value
http://javadude.com/articles/passbyvalue.htm
etc. ...

edit:
original von Oracle:


> Reference data type parameters, such as objects, are also *passed into methods by value*. This means that when the method returns, the passed-in reference still references the same object as before. _However_, the values of the object's fields _can_ be changed in the method, if they have the proper access level.


----------



## 4a61766120617274697374 (23. Jul 2016)

Du hast recht! Man muss aber eben achten, dass beide Referenzen in meinem bsp. auf das gleiche Objekt zeigen.


----------



## InfectedBytes (23. Jul 2016)

Das ist richtig, habe ich auch nie geleugnet^^
Aber bei der Parameterübergabe, geht es eben um die Variable selber, welche entweder ein primitiver Typ ist oder eine Referenz. Das Objekt (also dessen Felder) auf welches gezeigt wird kann dabei verändert werden


----------



## Xyz1 (23. Jul 2016)

mrBrown hat gesagt.:


> In Java ists leicht:
> primitive Datentype->CallByValue, Objekte->CallByRef
> 
> int wäre als CbV, int[] CbR



Gut, dass jemand noch mal gepostet hat, dass es in Java ausschließlich CbV lt. Definition gibt. Und das von dir, wo du alles besser wissen _*möchtest*_, hätte ich nicht erwartet. Desweiteren sind eure Erklärungen alle etwas schwach, nicht so, wie aus dem Lehrbuch...


----------



## thecain (23. Jul 2016)

Gut das du das jetzt richtiggestellt hast. Ahh... ne doch nicht

/e http://www.javaranch.com/campfire/StoryPassBy.jsp


----------



## Xyz1 (23. Jul 2016)

So steht es nun mal ausschließlich, eindeutig in der JLS, welche du kennen möchten würdest^^


----------



## VfL_Freak (25. Jul 2016)

Moin,

hier vlt. noch ein Link, der es IMHO ganz gut erklärt:
http://blog.gungfu.de/archives/2005...y-value-und-call-by-reference/comment-page-1/

Gruß Klaus


----------



## Flown (25. Jul 2016)

Hier mal die offiziellen Erklärungen: JLS 8.4.1


> When the method or constructor is invoked (§15.12), the values of the actual argument expressions initialize newly created parameter variables, each of the declared type, before execution of the body of the method or constructor. The _Identifier_ that appears in the _DeclaratorId_ may be used as a simple name in the body of the method or constructor to refer to the formal parameter.


Dann auch noch aus den Tutorial-Seiten.


----------

