# call by reference?



## Study123 (16. Apr 2011)

Hallo zusammen,

ich habe eine Frage zu call by reference und JAVA, da ich das noch nicht so ganz verstanden habe:

Bei C++ wird das call by reference z.B. so abgewickelt:



> #include <cstdlib>
> #include <iostream>
> 
> using namespace std;
> ...



Im Internet hab ich schon gelesen, dass so etwas bei JAVA mit primitiven Datentyp nicht abgewickelt werden kann. Gibt es dann gar keine andere Möglichkeit? Was mir als einiziges einfällt ist Verwendung von Wrapper Klassen (aber ich denke bei Wrapper Klassen kann man die Werte auch nicht so leicht ändern, da sie die Sichtbarkeit "final" haben?:


```
int i = 12;
Integer io = new Integer( i );
  io = new Integer( io.intValue() + 1 );
  i = io.intValue();
```


Wie funktioniert das denn dann genau bei JAVA?:
Laut Internet gibt es bei JAVA nur "call by value"?
Aber wenn ich bei Objekten die Werte übergebe, wie können dann die werte geändert werden?


Ich habe dazu folgenden Text gefunden:

"Objektvariablen sind Referenzen, also Zeiger. Zwar werden sie auch bei der Übergabe an eine Methode per Wert übergeben. (call by value) Da innerhalb der Methode aber der Zeiger auf das Originalobjekt zur Verfügung steht (wenn auch in kopierter Form) wirken sich die Veränderungen an dem Objekt natürlich direkt auf das Originalobjekt aus und sind somit für den Aufrufer der Methode sichtbar. Wie in allen anderen Programmiersprachen entspricht die call by value - Übergabe eines Zeigers damit natürlich genau der Semantik von call by reference.

Kann mir das vielleicht jemand einfach erklären?

Danke 

Viele Grüße!


----------



## Volvagia (16. Apr 2011)

Wrappler haben nicht umbedingt final. Der einfachste Wrappler wäre wohl ein Array:


```
public static void main(String[] args)
{
	int[] array = new int[1];
	array[0] = 1;
	wechsel(array);
	System.out.println(array[0]);
}
private static void wechsel(int[] array)
{
	array[0] = 2;		
}
```

Bei final wäre das natürlich genausowenig ein Problem:


```
public static void main(String[] args)
{
	final int[] array = new int[1];
	array[0] = 1;
	wechsel(array);
	System.out.println(array[0]);
}
private static void wechsel(int[] array)
{
	array[0] = 2;		
}
```

Das bedeutet ja nur, dass die Variable nicht verändert werden kann, nicht dass das Objekt nicht verändert werden kann.


----------



## Final_Striker (16. Apr 2011)

hier stand Quatsch.^^


----------



## Final_Striker (16. Apr 2011)

Study123 hat gesagt.:


> Wie funktioniert das denn dann genau bei JAVA?:
> Laut Internet gibt es bei JAVA nur "call by value"?
> Aber wenn ich bei Objekten die Werte übergebe, wie können dann die werte geändert werden?



z.B. so:


```
public static void main(String[] args) {

		Integer a = 5;
		Integer b = 1;
		Integer[] arr = new Integer[]{a,b};
		
		System.out.println("a=" + arr[0]);
		System.out.println("b=" + arr[1]);

		System.out.println("tausche...");
		swap(arr);

		System.out.println("a=" + arr[0]);
		System.out.println("b=" + arr[1]);
	}

	public static void swap(Integer[] arr) {
		Integer temp = arr[0];
		arr[0] = arr[1];
		arr[1] = temp;
	}
```


----------



## Study123 (16. Apr 2011)

Danke für die Antworten!

@Final Striker

Die Klasse "Integer" ist ja solch eine Wrapper - Klasse, oder?

Aber wie funktioniert der Tausch denn dann genau? Das ist ja kein "call by value" und auch kein direkter "call by reference"?

Ich übergebe anscheinend den Pointer auf den Speicherbereich des Arrays an die Methode? 
Ist dann hier ein Unterschied zwischen Pointer und Referenz?

@ Volvagia

Welchen Sinn hat dann final hier? Wie könnte ich das Array denn verändern, wenn ich "final" nicht schreiben würde? 

Viele Grüße!


----------



## Illuvatar (16. Apr 2011)

Mal noch ein Link auf den FAQ-Beitrag.
Kurz nochmal: Java kennt kein Call by Reference, alles was so aussieht kommt daher dass die Speicheradresse des Objekts _by Value_ übergeben wird, aber immernoch auf das gleiche Objekt verweist. (Man kann es sich zumindest so vorstellen...)



> Die Klasse "Integer" ist ja solch eine Wrapper - Klasse, oder?


Ja, und sie ist immutable, deshalb nicht geeignet um Call by Reference zu simulieren. Das passiert auch in Final Strikers Beispiel nur durch das Array, er hätte genausogut 
	
	
	
	





```
int[]
```
 verwenden können.



> Ist dann hier ein Unterschied zwischen Pointer und Referenz?


Soweit ich weiß ist das grundsätzlich das gleiche, man nennt es aber nur Pointer wenn man (wie in C) damit (mit den konkreten Adressen) rechnen kann.



> Wie könnte ich das Array denn verändern, wenn ich "final" nicht schreiben würde?


Auf irgendeine Art und weise, die mit 
	
	
	
	





```
array =
```
 beginnt.


----------



## omglolrofl (17. Apr 2011)

du kannst einen wrapper nehmen, dessen attribute - seis über methoden, seis direkt - verändert werden können.

bei cbv werden bei referenzen die referenz kopiert, das hat den anschein, als wäre es cbr (wo nur neue namen für dieselbe variable/stelle benutzt werden). klar?


----------



## Study123 (17. Apr 2011)

Hallo!

Danke für eure Hilfe, ich bin allerdings noch ein bisschen unsicher. Ich versuche es mal mit meinen eigenen Worten wiederzugeben, bzw. was ich von C++ gelernt habe:

*Call by Value:*
Es werden die Attribute des Objektes an die aufgerufene Methode übergeben, also wird eine Kopie des Objektes in der Methode erstellt. (Die Adresse im Speicher wird nicht übergeben).

*Call by Reference:*
Es wird ein Zeiger auf das Objekt, bzw. die Attribute des Objektes an die aufgerufene Methode übergeben (Die Adresse im Speicher wird übergeben)

Bei C++ gibt es beide Möglichkeiten (man kann bei C++ eine swap Funktion mit primitiven Datentypen abwickeln, indem man Call by Reference verwendet)


Nun habe ich gelesen, dass Java nur Call by Value verwendet. Damit kann doch meine oben stehende Definition nicht korrekt sein? 
Bei Java wird doch die Referenz (mit Referenz wird doch ein Verweis auf die Speicheradresse bezeichnet, oder??) des Objektes bzw. des Attributes an die aufgerufene Methode übergeben?

Sind meine Defintionen korrekt?

Danke!

Viele Grüße


----------



## maki (17. Apr 2011)

> Nun habe ich gelesen, dass Java nur Call by Value verwendet. Damit kann doch meine oben stehende Definition nicht korrekt sein?


Doch, ist korrekt.
Hast nur übersehen dass Java Referenzen (das sind soz. Zeiger ohne Arithmetik) kopiert werden, nicht die Objekte selber.
Damit ist CBV umgesetzt. Primitive werden kopiert, Referenzen auch.

Der Begriff "Reference" in "Call by Reference" hat rein gar nix mit Java Referenzen zu tun.
Eine Referenz ist in C++ was anderes als in Java 



> Sind meine Defintionen korrekt?


Ja.


----------



## Noctarius (17. Apr 2011)

Bei "CallByValue" (das ist nicht wirklich was Java macht) sollte dann nicht stehen "es wird eine Kopie des Objektes angelegt", sondern "es wird eine neue Referenz auf den selben Speicherbereich angelegt wie das original Objekt".

Java nutzt so etwas wie "CallByReferenceCopy" (dafür gibt es auch einen richtigen Namen der mir gerade entfallen ist, steht irgendwo in der Java Spec). Es wird nur die Speicherreferenz (quasi der Pointer) kopiert, nicht das gesamte Objekt.


----------



## Study123 (17. Apr 2011)

Hallo!

Danke für die Hilfe!  

Kann mir hier vielleicht noch jemand helfen wie das bei JAVA genau bezeichnet wird? Ich hatte nämlich nur call by value und call by reference im Kopf, dadurch bin ich wohl durcheinander gekommen 

Hier steht leider auch nur call by value:
http://www.java-forum.org/allgemeines/4904-call-value-call-reference.html

Ich hab jetzt auch ca ein dreiveirtel Stunde in der Java Language Specification gesucht:
The Java Language Specification

Allerdings auch nicht was gefunden (Ich habe nach "call" in der PDF Datei gesucht und alle Fundstellen betrachtet, evtl. ist mir die passende durchgerutscht..  )

Bitte um Hilfe! 

Dank!!

Gruß


----------



## Noctarius (17. Apr 2011)

Ok hab noch mal nachgesehen, es wird auch hier CallByValue genannt, aber eben mit dem Zusatzsatz "as primitive value or reference pointer".

Parameter passing in Java - by reference or by value? Hier ist noch mal eine schöne Beschreibung.


----------



## omglolrofl (17. Apr 2011)

Noctarius hat gesagt.:


> Java nutzt so etwas wie "CallByReferenceCopy" (dafür gibt es auch einen richtigen Namen der mir gerade entfallen ist, steht irgendwo in der Java Spec).



nö, das fantasiewort nirgends erwähnt.....


----------



## Firephoenix (17. Apr 2011)

Hi,
der Begriff ist aber an sich richtig.
Bsp du hast ein ArrayList-Objekt al1 das auf die ArrayList im Speicher mit der ID 19 zeigt.
und ein anderes al2, das auf die ArrayList im Speicher mit der ID 24 zeigt.
also
al1 -> ID 19
al2 -> ID 24
welche Werte an den Ids stehen ist ja egal.
Jetzt übergibst du beide einer Methode als Parameter x und y
du hast jetzt also zusätzlich
x -> ID 19
y -> ID 24

änderst du jetzt x (z.b. indem du dort Elemente hinzufügtst), wirkt sich das auf ID 19 aus, du änderst also auch al1.
versuchst du jetzt x und y über einen dreieckstausch zu traden hast du sowas:
temp -> x -> 19
x -> y -> 24
y -> temp -> 19
du hast jetzt zwar in der Funktion über = Zuweisungen x und y getauscht,
dieser "Zeigertausch" beeinflusst allerdings nicht al1 und al2, die zeigen weiter munter auf ihre Anfangs-Ids. Und eben diese zu swappen ist so nicht möglich.
Gruß


----------



## Noctarius (17. Apr 2011)

Gut, dass das Wort in Anführungsstrichen stand *Augen roll*


----------



## Study123 (17. Apr 2011)

Hallo!

Danke noch mal für eure Hilfe!

@Firephoenix:

Ist das jetz so, dass sich Änderungen bei y auf den Speicherbereich von al1 auswirken und x auf al2?

Wie könnten man den den Tausch dann in der Methode abwickeln?

Danke!


----------



## omglolrofl (17. Apr 2011)

Noctarius hat gesagt.:


> Gut, dass das Wort in Anführungsstrichen stand *Augen roll*



das zu behaupten, es werde in der jls so erwähnt, stand aber nicht in anführungszeichen oder?

viel eher ist es nämlich so, das cbr sich bei referenzen wie cbv verhält; nicht umgekehrt


----------



## Noctarius (17. Apr 2011)

Es steht aber da "dass die richtige Bezeichnung da steht"... Wer lesen kann...

Also noch mal ganz klar: Primitive Datentypen werden als Wertekopie übergeben, Referenzen als Kopie des "Pointer" (also Kopie der Speicherstelle).

Eine Referenz ist eben nur eine Referenz und nicht das Objekt selber.


----------



## Study123 (17. Apr 2011)

Hi,

ich hab das mit dem Tauschen mal kurz programmiert:


```
public class Tauschen {
	
	public static void swap  (int[] x, int[] y) {
		
		int[] temp;
		temp = x;
		x = y;
		y = temp;
		
		System.out.println("Der Tausch in der Methode:");
		
		System.out.println (x[0]);
		System.out.println(y[0]);
		
	}
	

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		
		int [] al1 = new int [3];
		int [] al2 = new int [3];
		
		al1 [0] = 3;
		al2[0] = 4;
		
		System.out.println("Vor dem Tausch:");
		System.out.println(al1[0]);
		System.out.println(al2[0]);
		
		swap(al1, al2);
		
		System.out.println();
		System.out.println();
		
		System.out.println("NAch dem Tausch in der main:");
		System.out.println(al1[0]);
		System.out.println(al2[0]);
		
	}

}
```

Ich hab das Prinzip verstanden, also 

al1 zeigt auf einen Speicherbereich ID19
al2 zeigt auf einen Speicherbereich ID24

In der Methode ist es zu Beginn so:

x zeigt auf Speicherbereich ID19
y zeigt auf Speicherbereich ID24

dann wird getauscht

temp verweist auf ID19
x verweist auf ID24
y verweist auf ID19
(NUN EXISTIEREN JA INSGESAMT 3 REFERENZEN AUF DEN SPEICHERBEREICH ID19?)

Was passiert dann eigetnlich beim Verlassen der Methode? Bleiben die Referenzen aktiv oder werden diese vom Garbage Collector aufgeräumt?


*Wo sich bei mir noch Fragen auftun: Ist es wirklich nicht möglich, diesen Tausch in der Methode durchzuführen?*

Danke!

Viele Grüße


----------



## Noctarius (17. Apr 2011)

Nein ist es nicht. Nur Objekte in einem Array können getauscht werden, da du hier direkt die Referenz im Array änderst wenn du etwas Neues zuweist.


----------



## omglolrofl (17. Apr 2011)

Noctarius hat gesagt.:


> Es steht aber da "dass die richtige Bezeichnung da steht"... Wer lesen kann...



tu doch nicht so, die richtige bezeichnug ist cbv und nichts anderes steht da. das kann man doch auch gleich sagen oder?


----------



## Study123 (17. Apr 2011)

Hi,



> Nein ist es nicht


meinst du damit dass es nicht möglich ist so etwas durchzuführen?


ich hab das noch mal probiert:


```
public class tauschen {

	
	public static void swap  (int[] x, int[] y) {
		
		int[] temp;
		//temp referenziert nun auch auf den Speicherbereich von x und al1
		temp = x;
		
		//der Speicherbereich, auf den temp[0], x[0] und al1[0] verweisen, erhält den Wert auf den y[0]
		//verweist, hier also 4.
		x [0] = y [0];
		y [0] = temp [0];
		
		System.out.println("Der Tausch in der Methode:");
		
		System.out.println (x[0]);
		System.out.println(y[0]);
		
	}
	

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		
		int [] al1 = new int [3];
		int [] al2 = new int [3];
		
		al1 [0] = 3;
		al2[0] = 4;
		
		System.out.println("Vor dem Tausch:");
		System.out.println(al1[0]);
		System.out.println(al2[0]);
		
		swap(al1, al2);
		
		System.out.println();
		System.out.println();
		
		System.out.println("NAch dem Tausch in der main:");
		System.out.println(al1[0]);
		System.out.println(al2[0]);
		
		
	}

}
```

Allerdings klappt das so nicht. Aber wie geht das dann konkret in diesem Beispiel? Sind solche Änderungen dann gar nicht erwünscht bei Java?

Gruß


----------



## Michael... (17. Apr 2011)

Study123 hat gesagt.:


> ```
> int[] temp;
> //temp referenziert nun auch auf den Speicherbereich von x und al1
> temp = x;
> ```


Wie hier richtig angemerkt referenzieren x und temp auf das selbe (Array) Objekt.


Study123 hat gesagt.:


> ```
> x [0] = y [0];
> y [0] = temp [0];
> ```


Wie oben richtig angemerkt referenzieren x und temp auf das selbe (Array) Objekt. ;-)

So würde es funktionieren, aber ob dass der Sinn ist?

```
public static void swap(int[] x, int[] y) {
	int temp = x[0];
	x[0] = y[0];
	y[0] = temp;
	System.out.println("Der Tausch in der Methode:");
	System.out.println(x[0]);
	System.out.println(y[0]);
}
```


----------



## Noctarius (17. Apr 2011)

omglolrofl hat gesagt.:


> tu doch nicht so, die richtige bezeichnug ist cbv und nichts anderes steht da. das kann man doch auch gleich sagen oder?



Nur weil es da steht macht es die Sache ja nicht besser, die Bezeichnung ist absolut verwirrend und fertig... Egal wie du meinst.


----------



## Study123 (18. Apr 2011)

Guten Morgen,

danke!

Aber warum geht das nun doch? 

Noctarius hat ja geschrieben, dass nur Objekte in einem Array getauscht werden können. Aber sind in den arrays al1 und al2 Objekte oder variablen eines int - Datentypes?

Warum funktioniert der Tausch dann so?

Ich hab meine Gedanken mal hinzugefügt:


```
public static void swap  (int[] x, int[] y) {
		
		int temp;
		//temp bekommt den Wert von x[0] zugewiesen => Verstanden
		//Frage: Verweist temp auf den Speicherbereich von al1? Ich glaube dass temp seinen
		//eigenen Speicherbereich hat?
		temp = x [0];
		
		//x[0] und y[0] verweisen nun auf den gleichen Speicherbereich von al2
		//müsste dann nicht temp auch auf den gleichen Speicherbereich verweisen (außer temp hat 
		//eigenen Speicherbereich)
		x [0] = y [0];
		//Nun bekommt y[0] den Wert von temp zugewiesen. Da allerdins x[0] auch auf den gleichen Speicherbereich
		//referenziert, müsste doch nun bei x[0] der Wert überschrieben werden?
		y [0] = temp;
		
		System.out.println("Der Tausch in der Methode:");
		
		System.out.println (x[0]);
		System.out.println(y[0]);
		
	}
```

Viele Grüße


----------



## Noctarius (18. Apr 2011)

Du tauscht so die Referenzen / Objekte / Werte innerhalb des Arrays. Bei der Übergabe wird nur die Referenz zum Array selber kopiert, eben nicht das gesamte Array. Damit sind die Referenzen innerhalb des Arrays gleich. Visualisiert etwa so:

Gegeben:

```
Speicherzelle Nr: Wertetyp[Datentyp/Name][verknüpfte Speicherzelle(n)]

Speicherzelle 1: Object[Int-Array][2,3]
Speicherzelle 2: Object[Int-Array][5,6]

Speicherzelle 3: primitive[int][100]
Speicherzelle 4: primitive[int][200]

Speicherzelle 5: primitive[int][300]
Speicherzelle 6: primitive[int][400]

Speicherzelle 7: Referenz[foo][1]
Speicherzelle 8: Referenz[bar][2]
```




```
public void swap(int[] foo, int bar[]) {
    bar[0] = foo[0];
    bar[1] = foo[0];
}
```

erzeugt:

```
Speicherzelle Nr: Wertetyp[Datentyp/Name][verknüpfte Speicherzelle(n)]

Speicherzelle 1: Object[Int-Array][2,3]
Speicherzelle 2: Object[Int-Array][2,3]

Speicherzelle 3: primitive[int][100]
Speicherzelle 4: primitive[int][200]

Speicherzelle 7: Referenz[foo][1]
Speicherzelle 8: Referenz[bar][2]
```




```
public void swap(int[] foo, int bar[]) {
    int b = bar[0];
    int c = bar[1];
    bar[0] = foo[0];
    bar[1] = foo[0];
    foo[0] = b;
    foo[1] = c;
}
```

erzeugt:

```
Speicherzelle Nr: Wertetyp[Datentyp/Name][verknüpfte Speicherzelle(n)]

Speicherzelle 1: Object[Int-Array][5,6]
Speicherzelle 2: Object[Int-Array][2,3]

Speicherzelle 3: primitive[int][100]
Speicherzelle 4: primitive[int][200]

Speicherzelle 5: primitive[int][300]
Speicherzelle 6: primitive[int][400]

Speicherzelle 7: Referenz[foo][1]
Speicherzelle 8: Referenz[bar][2]
```

und so weiter.


----------



## omglolrofl (18. Apr 2011)

cbv besagt eben, dass zuweisungen an parameter keinen effekt auf variablen des aufrufers haben, die als parameter übergeben worden sind. nicht mehr, nicht weniger. änderungen auf dem von variable und parameter referenzierten objekt machen sich natürlich auch für den aufrufer bemerkbar 
man muss isch bewusst machen, das der wert einer objektvariablen eben eine referenz ist, nicht das objekt selbst.
@Noctarius: mag ja sein, das das für dich verwirrend ist, andere sehn das vieelicht nicht so.


----------



## Noctarius (18. Apr 2011)

omglolrofl hat gesagt.:


> @Noctarius: mag ja sein, das das für dich verwirrend ist, andere sehn das vieelicht nicht so.



Für manche mag die Bibel stimmen, für andere nicht ... eyeyey was für Aussagen. Ich denke wir haben mittlerweile geklärt, dass es CallByValue heißt ... immer diese Rumreitereien...


----------



## roflcopter (18. Apr 2011)

Noctarius hat gesagt.:


> Für manche mag die Bibel stimmen, für andere nicht ... eyeyey was für Aussagen. Ich denke wir haben mittlerweile geklärt, dass es CallByValue heißt ... immer diese Rumreitereien...



wenn für java die jls nicht "stimmt", an was glauben sie dann? an eine von dir gegründete religion? LoL


----------



## Noctarius (18. Apr 2011)

So die Nebendiskussion ist jetzt mal zu Ende, du hast Recht und ich meine Ruhe. Dieses kindische Gehabe nach dem Motto "ich habe aber Recht" bringt den TO nicht weiter. Abgesehen davon sind deine "Nicks" mehr als nur peinlich, aber das merkst du scheinbar nicht. Also lass' einfach deine Kommentare wenn du nichts konstruktives beitragen kannst.

Es heißt CallByValue und fertig...


----------



## Study123 (18. Apr 2011)

Hi!

Danke für das Beispiel! 

Ich hab dazu noch eine Frage.

Ist es absichtlich, dass zweimal 


```
bar[1] = foo[0];
```

steht oder sollte das nicht


```
bar[1] = foo[1];
```

heißen?

Gruß


----------



## Marco13 (18. Apr 2011)

Kleiner Einschub: Das aus dem ersten Beitrag
void wechsel (int *a, int *b) {
ist auch nicht Call By Reference. Das ist auch call by value, genau wie in Java. Die Value ist in diesem Fall ein Pointer. Ähnlich wie die Referenz in Java. 

"Echtes" call by reference wäre

```
void wechsel (int& a, int& b) 
{
    int t = a;
    a = b;
    b = t;
}
```
mit dem Aufruf
wechsel(a, b);


----------



## Noctarius (18. Apr 2011)

Study123 hat gesagt.:


> steht oder sollte das nicht
> 
> 
> ```
> ...



Ja sollte es


----------



## Study123 (18. Apr 2011)

Hi, 

ich bin's noch mal. 

Das Thema lässt mich irgendwie noch nicht in Ruhe, ich habe dazu noch mal folgendes gefunden:

Im Buch "Java ist auch eine Insel" (8. Auflage) steht unter Punkt 1.3.4

"In JAVA gibt es keine Zeiger (engl. pointer) ... da eine Objektorientierte Programmiersprache ohne verweise nicht funktioniert, werden Referenzen eingeführt..."


Dann in der JLS:
Types, Values, and Variables

The reference values (often just references) are pointers to these objects, and a special null reference, which refers to no object.


Ich habe im Buch "Grundkurs Softwareentwicklung mit C++ auf Seite 274 ein Skizze zu Übergabe per Zeiger und Übergabe per Referenz gefunden:

Es wird so beschrieben: (sinngemäß wiedergegeben von mir)
Übergabe per Zeiger:
Die Speicheradresse der Variablen wird kopiert und die Kopie an eine Funktion übergeben


Übergabe per Referenz:
Die Speicheradresse der Variablen wird direkt an die Funktion kopiert, Änderungen erfolgen also direkt und dauerhaft im Variableninhalt.


Wenn ich mir diese Definition anschaue, dann würde ich klar sagen, dass JAVA "Übergabe per Zeiger" verwendet. Allerdings steht in "JAVA ist auch eine Insel" Dass Zeiger hier nicht existieren... Irgendwie wiederspricht sich das.

Viele Grüße


----------



## Marco13 (18. Apr 2011)

Vielleicht klingt es im ersten Moment so. In Java gibt es keine Zeiger. Nur Referenzen. Aber eine Referenz in Java ist etwas anderes als eine Referenz in C++. Eine Referenz in Java ist fast das gleiche wie ein Zeiger in C++. (Abgesehen davon, dass man keine Arithmetik damit betreiben kann). 

Das ist vielleicht ein bißchen verwirrend wegen der Begrifflichkeiten: "Referenz" ist in beiden Sprachen unterschiedlich definiert. Darüberhinaus sind "Referenz" und insbesondere "Zeiger" (Pointer) sehr allgemeine Begiffe, so dass vermeintlich falsche Aussagen dadurch entstehen, dass sie in ihrer allgemeinen Bedeutung verwendet werden, man aber glaubt, es wären die streng definierten Begriffe gemeint. Als Beispiel:
_The reference values (often just references) are pointers to these objects..._
"Pointer" ist hier in der allgemeinen Bedeutung zu verstehen - das heißt: Referenzen zeigen (oder verweisen) auf etwas. Es sind nicht "Pointer" wie in C++, wo dieser Begriff streng definiert ist, als sowas wie eine Variable, die eine Speicheradresse enthält. Um die Verwirrung komplett zu machen: Manchmal werden Zeiger in C++ umgangssprachlich als "Referenzen" auf irgendein Objekt bezeichnet, IMHO schrecklich unpräzise und verwirrend, aber nicht unüblich...


----------



## 2XS (19. Apr 2011)

Hi,

sorry, dass ich das Thema hijacke, aber ich habe dann auch noch eine Verständnisfrage dazu.

Beispielcode:

```
DieInSet d6 = new DieInSet(6); // Erzeugt ein 6 seitiges Würfelobjekt
		DieInSet[] dice = new DieInSet[2]; // Array aus Würfelobjekten

		dice[0] = d6;
		dice[1] = d6;
```

Frage:
Enthält dice[0] das selbe Objekt wie dice[1] (eine Referenz auf den selben Speicherbereich)?
Wenn ja, wie kann ich erzwingen, dass dice[0] und dice[1] unterschiedliche Würfelobjekte beinhalten?


Grüße,

Andy


----------



## Noctarius (19. Apr 2011)

Ja es sind beide Instanzen die selben. Entweder erstellst du einfach 2 Instanzen des Würfel-Objektes (einfacher Weg) oder du musst schauen ob du "klonen" kannst. Ergo nimm den ersten Weg


----------



## AmunRa (19. Apr 2011)

Ja dice[0] und dice[1] zeigen auf das selbe Objekt. 
Dazu musst du dein Object klonen. Hierfür gibt es mehrere Strategien. Entweder du schreibst dir einen Kopierkonstruktor oder du implementierst eine clone() Methode. (Ich gehe hier davon aus,dass DieInSet eine eigene Klasse von dir ist.)

In Java gibt es leider keine Möglichkeit das Object direkt von java kopieren zu lassen


----------



## maki (19. Apr 2011)

> Wenn ja, wie kann ich erzwingen, dass dice[0] und dice[1] unterschiedliche Würfelobjekte beinhalten?


Immutables sind besser.

Falls es doch Kopien sein müssen(?):
Copy Konstruktoren sind so... rückständig, dann doch lieber eine Factory Methode anstatt eines Copy Konstruktors.

Oder eben gleich immutables


----------



## 2XS (19. Apr 2011)

Momentan habe ich es so gelöst, dass dem Constructor von SetOfDice (eine weitere eigene Klasse) das Array dice (vom Typ DieInSet[]) übergeben wird. Im Konstruktor werden dann neue Objekte von DieInSet gecloned. Sauberer wäre dann aber wohl eine clone Methode für DieInSet, oder?

Immutables und Factory Klassen oder Methoden sind mir noch neu. Von Ersteren habe ich zwar vor vielen Jahren, während der Ausbilung, mal im Zusammenhang mit Strings gehört. Von Letzteren lese ich aber gerade, bewusst, das erste Mal. Und nach etwas <Suchmaschine der Wahl einsetzen> Suche glaube ich, dass beides für meine Zwecke etwas über das Ziel hinaus schießt. Werde also wohl einfach eine clone Methode implementieren.


Grüße und vielen Dank,

Andy


P.S.: Echt hart wie schnell man etwas wieder vergisst, wenn man es nicht regelmäßig anwendet...


----------



## Michael... (19. Apr 2011)

Klar könnte man hier was mit einer Factory Klasse machen. Aber reicht es in diesem Fall nicht einfach aus ein zweites Objekt zu erzeugen? Oder hab ich irgendetwas überlesen?


Edit: Das hat jetzt allerdings nichts mit call by reference oder call by value zu tun. Man hätte da also ruhig einen eigenen Thread dazu aufmachen können.


----------



## 2XS (19. Apr 2011)

Wollte ja auch eigentlich nur eine kurze Antwort zu dem Array aus Objekten.


----------



## roflcopter (19. Apr 2011)

Marco13 hat gesagt.:


> Vielleicht klingt es im ersten Moment so. In Java gibt es keine Zeiger. Nur Referenzen. Aber eine Referenz in Java ist etwas anderes als eine Referenz in C++. Eine Referenz in Java ist fast das gleiche wie ein Zeiger in C++. (Abgesehen davon, dass man keine Arithmetik damit betreiben kann).
> 
> Das ist vielleicht ein bißchen verwirrend wegen der Begrifflichkeiten: "Referenz" ist in beiden Sprachen unterschiedlich definiert. Darüberhinaus sind "Referenz" und insbesondere "Zeiger" (Pointer) sehr allgemeine Begiffe, so dass vermeintlich falsche Aussagen dadurch entstehen, dass sie in ihrer allgemeinen Bedeutung verwendet werden, man aber glaubt, es wären die streng definierten Begriffe gemeint. Als Beispiel:
> _The reference values (often just references) are pointers to these objects..._
> "Pointer" ist hier in der allgemeinen Bedeutung zu verstehen - das heißt: Referenzen zeigen (oder verweisen) auf etwas. Es sind nicht "Pointer" wie in C++, wo dieser Begriff streng definiert ist, als sowas wie eine Variable, die eine Speicheradresse enthält. Um die Verwirrung komplett zu machen: Manchmal werden Zeiger in C++ umgangssprachlich als "Referenzen" auf irgendein Objekt bezeichnet, IMHO schrecklich unpräzise und verwirrend, aber nicht unüblich...



ähm, es gilt

```
nicht refrenz != zeiger
```

es gilt 
	
	
	
	





```
refrenz == zeiger
```

alles andere hast du aus der werbung für bare münze gehalten ^^


----------



## Marco13 (19. Apr 2011)

Mir ist nicht ganz klar, was du mir sagen willst, und ob nicht assoziativ ist. 
(Vielleicht sollte ich das nicht in Anführungzeichen setzen... :reflect: ... also)
... ob "nicht" assoziativ ist.

int x;
int &y = x; // y ist eine Referenz auf x
int *z = &x; // z ist ein Zeiger auf x


----------



## roflcopter (19. Apr 2011)

Marco13 hat gesagt.:


> Mir ist nicht ganz klar, was du mir sagen willst, und ob nicht assoziativ ist.
> (Vielleicht sollte ich das nicht in Anführungzeichen setzen... :reflect: ... also)
> ... ob "nicht" assoziativ ist.



hab extra drunter geschrieben, wie "nicht" zu interpretieren ist.



Marco13 hat gesagt.:


> [...]



nicht noch mehr schwachfug verbreiten. ^^


----------



## Marco13 (19. Apr 2011)

Dann definier' mal, was [c]nicht referenz[/c] sein soll. Aber erst nachdem du [8] References, C++ FAQ gelesen hast.


----------



## roflcopter (19. Apr 2011)

es gilt nicht, dass das und das ist. was ist missverständlich?


----------



## Illuvatar (19. Apr 2011)

roflcopter hat gesagt.:


> Marco13 hat gesagt.:
> 
> 
> > [...]
> ...



Hmm, wem vertraue ich mehr: Marco13 mit 11000 Beiträgen, bei denen ich noch nicht einen schwachen gesehen habe - oder einem anonymen User der sich roflcopter nennt?


----------



## Marco13 (19. Apr 2011)

Wenn es nicht eigentlich nicht so nicht unbedeutend wäre, würde ich jetzt fast mein erstes 
	

	
	
		
		

		
			





 vergeben  

Um mal auf die ähnlich unpräzise Meta-Ebene zu gehen:
(nicht (referenz != zeiger)) != ((nicht referenz) != zeiger)
zumindest solange die Prioritäten der Operatoren !=,== und nicht nicht geklärt sind.


----------



## roflcopter (19. Apr 2011)

Illuvatar hat gesagt.:


> Hmm, wem vertraue ich mehr: Marco13 mit 11000 Beiträgen, bei denen ich noch nicht einen schwachen gesehen habe - oder einem anonymen User der sich roflcopter nennt?



umsowahrscheinlicher ist es, das er auch mal ein paar "schwache" hat.



Marco13 hat gesagt.:


> Wenn es nicht eigentlich nicht so nicht unbedeutend wäre, würde ich jetzt fast mein erstes
> 
> 
> 
> ...



man darfst annehmen: priorität(nicht) < priorität(!=)


----------



## Study123 (16. Apr 2011)

Hallo zusammen,

ich habe eine Frage zu call by reference und JAVA, da ich das noch nicht so ganz verstanden habe:

Bei C++ wird das call by reference z.B. so abgewickelt:



> #include <cstdlib>
> #include <iostream>
> 
> using namespace std;
> ...



Im Internet hab ich schon gelesen, dass so etwas bei JAVA mit primitiven Datentyp nicht abgewickelt werden kann. Gibt es dann gar keine andere Möglichkeit? Was mir als einiziges einfällt ist Verwendung von Wrapper Klassen (aber ich denke bei Wrapper Klassen kann man die Werte auch nicht so leicht ändern, da sie die Sichtbarkeit "final" haben?:


```
int i = 12;
Integer io = new Integer( i );
  io = new Integer( io.intValue() + 1 );
  i = io.intValue();
```


Wie funktioniert das denn dann genau bei JAVA?:
Laut Internet gibt es bei JAVA nur "call by value"?
Aber wenn ich bei Objekten die Werte übergebe, wie können dann die werte geändert werden?


Ich habe dazu folgenden Text gefunden:

"Objektvariablen sind Referenzen, also Zeiger. Zwar werden sie auch bei der Übergabe an eine Methode per Wert übergeben. (call by value) Da innerhalb der Methode aber der Zeiger auf das Originalobjekt zur Verfügung steht (wenn auch in kopierter Form) wirken sich die Veränderungen an dem Objekt natürlich direkt auf das Originalobjekt aus und sind somit für den Aufrufer der Methode sichtbar. Wie in allen anderen Programmiersprachen entspricht die call by value - Übergabe eines Zeigers damit natürlich genau der Semantik von call by reference.

Kann mir das vielleicht jemand einfach erklären?

Danke 

Viele Grüße!


----------



## Marco13 (19. Apr 2011)

Gut, dann ist jetzt zumindest eindeutig und unmißverständlich klar, dass du Unrecht hattest


----------



## roflcopter (3. Mai 2011)

_altes thema hervorgrab_

ich hab nochmal genau nach geguckt in einem anfängerbuch, dessen namen ich nicht nennen werden. es ist so, wie vermutet: weder in java *noch in c* gibt es echtes cbr...

das mit 
	
	
	
	





```
refrenz != zeiger
```
 ist auch ein märchen


----------



## Marco13 (3. Mai 2011)

*seufz*. Vielleicht fangen wir mal klein an: Stimmst du bei [c]C != C++[/c] zu?


----------

