Call by reference

C

C_A

Gast
Ich habe gerade folgenden Text gelesen: http://www.java-forum.org/allgemeines/4904-call-value-call-reference.html

Erstmal: bravo und danke an den Autor.

Ich bin konfus.

Java:
    public static void main(String[] args)
    {        
        Daten test = new Daten();
        test.zahl = 5; 

        String text = "alter Text";
        
        System.out.println(text + " " + test.zahl);
        swap(test, text);
        System.out.println(text + " " + test.zahl);
    }
    
    public static void swap(Daten werte, String ausgabe) 
    { 
        werte.zahl = 50000; 
        ausgabe = "neuer Text";
    }
}

Ich deklariere zwei Variablen: einen String und einen Test von Typ Daten

Daten hat folgenden Code:
Java:
public class Daten
{
    public int zahl = 2;

}

Warum werden String und Daten anders behandelt? Wo ist der Unterschied zwischen diesen beiden Klassen? Bei Daten wäre das mit der Referenz ja klar: ich übergebe die Referenz auf ein Objekt, das in der Methode swap geändert wird. Aber warum funktioniert das bei String nicht? *grübelz*
 
Zuletzt bearbeitet von einem Moderator:
S

SlaterB

Gast
beim String änderst du nichts IM Objekt, das wäre
> ausgabe.ersterBuchstabe = "n";
geht bei String generell nicht, würde ansonsten aber wie bei Daten funktionieren
> werte.zahl = 50000;

----------

was du stattdessen machst, ist der lokalen Variablen einen neuen Wert zuzuweisen
> ausgabe = "neuer Text";
äquivalent wäre
> werte = new Daten(..);
was sich genausowenig auf den Aufrufer auswirkt
 

sambalmueslie

Bekanntes Mitglied
Hier noch ein kleines Beispiel zum nachvollziehen, was passiert:

Java:
package reference;

public class ReferenzTest {
	public class Daten {
		public int zahl = 2;

	}

	public static void main(final String[] args) {
		new ReferenzTest();
	}

	public ReferenzTest() {
		final Daten test = new Daten();
		test.zahl = 5;

		final String text = "alter Text";

		print(test, text);
		swap(test, text);
		print(test, text);
		swap2(test, text);
		print(test, text);
	}

	public void swap(final Daten werte, String ausgabe) {
		werte.zahl = 50000;
		ausgabe = "neuer Text";
		print(werte, ausgabe);
	}

	public void swap2(final Daten werte, String ausgabe) {
		werte.zahl = 50000;
		ausgabe = new String("ganz neuer Text");
		print(werte, ausgabe);
	}

	private void print(final Daten werte, final String text) {
		System.out.println("----------------------------------");
		System.out
				.println(" Daten : " + werte.zahl + " -> " + werte.hashCode());
		System.out.println(" Text : " + text + " -> " + text.hashCode());
	}

}

Output:

Code:
----------------------------------
 Daten : 5 -> 1671711
 Text : alter Text -> -771520745
----------------------------------
 Daten : 50000 -> 1671711
 Text : neuer Text -> -1816106622
----------------------------------
 Daten : 50000 -> 1671711
 Text : alter Text -> -771520745
----------------------------------
 Daten : 50000 -> 1671711
 Text : ganz neuer Text -> 329089468
----------------------------------
 Daten : 50000 -> 1671711
 Text : alter Text -> -771520745

Du siehst relativ leicht, dass für den String ein neues Objekt angelegt wird.

Gruß Oli
 
Zuletzt bearbeitet:
C

C_A

Gast
Tut mir leid, ich steh auf dem Schlauch.

Wenn ich eine Variable deklariere, sieht das doch so aus: String text = new String();

1. eine Variable text vom Typ String wird angelegt
2. auf dem heap wird ein Objekt new String() angelegt.
3. Der Zuweisungsoperator verbindet Heap-Objekt und Variable

Der Aufruf schreibe(text) ruft eine Methode auf, der als Parameter die Referenz von text übergeben wird. Damit greift schreibe() auf das Objekt, das in aller Seelenruhe auf dem Heap ruht, zu. Es gibt dann zwei Variablen mit derselben Referenz ... wäre ich von ausgegangen. Dass es nicht so ist, sehe ich ... aber warum nicht? Wo ist der Denkfehler .... ??? Bin immer noch konfus.
 

sambalmueslie

Bekanntes Mitglied
@Oli: ich teste es gleich mal .... hab's zu spät gesehen!

joa macht nix..

schau bitte das du die geänderte variante hast.. hab noch nen kleinen copy-paste fehler drinne gehabt.


Wenn du schreibst:
Java:
String text = new String("hallo welt");

dann wird ein neues objekt erstellt und das der Variablen "text" zugwiesen.
Diese ist eine Referenz auf das String Objekt.

Wenn du jetzt folgenes schreibst:
Java:
String text = new String("hallo universum");

dann wird wieder ein neues objekt erstellt und das der Variablen "text" zugewiesen.
die Referenz auf das "hallo welt"-Objekt geht verloren und wird mit der Referenz auf das "hallo universum" ersetzt:


Beispiel:

Java:
String text = new String("Hallo Welt");
String text2 = text;

System.out.println(text + ":" + text2);

text2 = new String("Hallo Universum");
System.out.println(text + ":" + text2);

Gruß Oli
 
C

C_A

Gast
Vorweg: Danke für Eure ausführlichen Posting und die Mühe, die dahintersteckt.

Okay, jetzt nochmal in Ruhe - hab's vorhin eher etwas übereilt getippt. Ich hatte den Artikel gelesen und bin erstmal erschrocken, weil ich nämlich auch mal gehört hatte dass es in Java Call by Referenz und Call by value gibt. Die klare Ansage, dass es so nicht ist, hat mich so verunsichert, dass ich die Logik wahrscheinlich nicht zu ende gedacht habe.

Verstehe ich das jetzt richtig? Beim Methodenaufruf kopiere ich die Referenz in den Parameter. Dann habe ich zwei Variablen, die auf ein und dasselbe Objekt verweisen - eine Variable des Aufrufers und eine lokale Variable innerhalb der Methode. Um bei dem Beispiel Von-Kopf-bis-Fuß zu bleiben: ich habe zwei Fernsteuerungen, die auf das gleiche Objekt programmiert sind.

Aber eben weil ich zwei Variablen habe, ist ein Befehl "parameter = new Daten();" innerhalb der Methode unschädlich für die Variable des Aufrufers.

So, wo ich noch hänge - und da hat Olis Code mich etwas verwirrt: der String hat eine andere Referenz (= HashCode?), also neues referenziertes Objekt .... wenn ich einen neuen Wert zuweise, also
Java:
text += " Zusatz";
oder
Java:
 text = text.toUpperCase();

Aber warum wird der String anders behandelt, als das Objekt vom Typ Daten? Warum wird kein neues Objekt angelegt, wenn ich sage
Java:
Daten test = new Daten(); 
test.zahl = 5; 

... Methodenaufruf ... 

parameter.zahl = 20;

Liegt die Antwort in Slaters Post?
beim String änderst du nichts IM Objekt, das wäre
> ausgabe.ersterBuchstabe = "n";
geht bei String generell nicht, würde ansonsten aber wie bei Daten funktionieren

Falls ich hier auf der richtigen Spur bin .... warum kann ich bei String nichts ändern? Warum wird bei String immer ein neues Objekt angelegt, wenn ich "den Text" ändere, und sei es durch eine Methode, die von der Klasse zur Verfügung gestellt wird?

Ist klar, woran ich hänge? Anders ausgedrückt: String und Daten werden hier auf den ersten Blick unterschiedlich behandelt. Und meine Frage geht in die Richtung: woher weiß ich, wo der - vermeintliche - Unterschied herkommt?

Grüße Florian

P.S. Nochmal zu dem Artikel: Wenn ich bei einfachen Datentypen den Wert kopiere und bei komplexen Datentypen die Referenz auf das Objekt habe ich doch eigentlich schon einen Call-by-value / Call-by-referenz .... ich bin nicht über C(++) zu Java gekommen, sondern über Delphi. Vermutlich deshalb ist mir die Grundaussage nicht ganz klar.
 

sambalmueslie

Bekanntes Mitglied
na vergiss mal das mit String und Daten unterschiedlich behandeln ..
der unterschied liegt darin, dass du einemal ein objekt selbst änders (String) und einmal eine Variable in einem Objekt.

der String lässt sich nicht manipulieren, sondern erzeugt immer einen neuen String, dadurch kannst du da nichts ändern.

das folgendes funktioniert, daran ist der compiler schuld
Java:
String test = "hallo Welt";

was eigentlich gemacht wird ist:

Java:
String test = new String("hallo Welt");

nehmen wir mal den folgenden Fall, dann wirst du keinen unterschied mehr feststellen:

Java:
public class MyString {
 public String text;
}

und jetzt manipulieren wir:

Java:
MyString mytext = new MyString();
mytext.text = "hallo welt";

System.out.println(mytext.text);

was passiert?
Es wird ein neues String Objekt erzeugt ("hallo welt")
und davon die Referenz wird in "text" gespeichert.

wenn du jetzt das ganze einer methode übergibst und dort den "text" änderst, wird sich das auch im Objekt ändern.
Denn du setzt "text" auf ein neues String Objekt, aber das MyString Objekt bleibt unverändert.

Gruß oli
 
C

C_A

Gast
Hallo,

ich glaube, so langsam rundet sich das Bild ;-)

Darf ich nochmal kurz auf den besagten Artikel zurückkommen?

P.S. Nochmal zu dem Artikel: Wenn ich bei einfachen Datentypen den Wert kopiere und bei komplexen Datentypen die Referenz auf das Objekt habe ich doch eigentlich schon einen Call-by-value / Call-by-referenz .... ich bin nicht über C(++) zu Java gekommen, sondern über Delphi. Vermutlich deshalb ist mir die Grundaussage nicht ganz klar.

Was meinst du zu meiner Frage?

Grüße
Florian
 

sambalmueslie

Bekanntes Mitglied
naja.. ich verstehe das so, java ist deutlich objektorientierter als z.b. c++

darum ist in Java alles eine Referenz und alles ein Objekt..
auch die "nativen Datentypen" (vgl. int und die Klasse Integer) beispielsweise..

darum hast du auch immer ein call by reference (wenn ich mich hier nicht irre ;)

im unterscheid dazu musst du in C++ beispielsweise darauf achten, wo du einen call by value hast und einen call by reference und hier werden evtl. dann objekte kopiert und so..
das hast du in java eigentlich nicht und musst dir da normalerweise keinen kopf drum machen.

du übergibts das objekt und arbeitest damit .. gut ist :)

tricky wird es halt, wenn du das objekt in der methode überschreibst so wie in deinem beispiel :)

gruß oli
 

Suinos

Bekanntes Mitglied
Alle Variablen sind Referenzen auf Objekte (oder primitive Objekte).
Alle Parameter werden durch value übergeben.

Florian_ hat gesagt.:
Aber warum wird der String anders behandelt, als das Objekt vom Typ Daten?
Sieh dir dein Beispiel genau an:
[JAVA=13]
public static void swap(Daten werte, String ausgabe)
{
werte.zahl = 50000;
ausgabe = "neuer Text";
}
[/code]
In Zeile 15 weist du dem Attribut
Code:
zahl
vom Objekt, auf welches [c]werte[/c] referenziert, einen neuen Wert zu. Dadurch hast du das Objekt verändert.
Von ausserhalb der Methode sieht das Objekt jetzt anders aus!

In Zeile 16 weist du der Variable [c]ausgabe[/c] ein neues Objekt zu. Das alte Objekt, auf welches vorher verwiesen wurde, hast du nicht angerührt.
Von ausserhalb der Methode sieht das Objekt noch immer gleich aus!
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
J Java call by Value oder Reference Java Basics - Anfänger-Themen 35
R Call-by-Value, Call-by-Reference, Call-by-Name Ausgabe Java Basics - Anfänger-Themen 1
X Verständnisproblem Call-By-Reference Java Basics - Anfänger-Themen 5
U Worin besteht der Unterschied zwischen call by reference und call by value? Java Basics - Anfänger-Themen 14
H call by reference & value Java Basics - Anfänger-Themen 14
B Call by Value/Reference Java Basics - Anfänger-Themen 4
Joew0815 Methoden Objekt als Methoden-Parameter - Kein call-by-reference? Java Basics - Anfänger-Themen 12
T Array prozedur, call by reference ? Java Basics - Anfänger-Themen 6
B Variablen Wie macht man eine call by reference mit primitiven Datentypen in Java? Java Basics - Anfänger-Themen 2
S call by reference? Java Basics - Anfänger-Themen 52
F Verständisproblem bzgl. nicht Vorhandensein von Call-by-reference Java Basics - Anfänger-Themen 2
B Call By reference (Null pointer exception) Java Basics - Anfänger-Themen 6
W call-by-reference-Effekt bei Objekten Java Basics - Anfänger-Themen 3
S "Call by Reference" Java Basics - Anfänger-Themen 12
M try-catch, call-by-reference, Streaming und Strings Java Basics - Anfänger-Themen 10
S call by reference Java Basics - Anfänger-Themen 7
F Wie kann ich call by reference umgehen? Java Basics - Anfänger-Themen 14
F Rekursive Aufrufe, Parameterübergabe, call by reference Java Basics - Anfänger-Themen 3
F Call-By-Reference umgehen Java Basics - Anfänger-Themen 4
B Call by Reference Java Basics - Anfänger-Themen 7
S call by reference vs. call by value - pls help Java Basics - Anfänger-Themen 7
K Eigene Annotations, Pre-/Post-/Call-Method Java Basics - Anfänger-Themen 6
G Klassen Call by Value auch bei Objekten? Java Basics - Anfänger-Themen 2
R Call By Referene? Java Basics - Anfänger-Themen 10
N Methode erfüllt nicht den zweck (Call by value) Java Basics - Anfänger-Themen 17
0 Call by value Java Basics - Anfänger-Themen 3
J Call by ... Java Basics - Anfänger-Themen 16
F java call jython Java Basics - Anfänger-Themen 7
C Unchecked Call? Wie Warnung beseitigen? Java Basics - Anfänger-Themen 3
I call to super must be first statement in constructor Java Basics - Anfänger-Themen 3
M Cannot make a static reference to the non-static method Java Basics - Anfänger-Themen 10
T Boolean by Reference Java Basics - Anfänger-Themen 6
T Schleifenindex "by reference" / "by value" Java Basics - Anfänger-Themen 13
O Socket by reference übergeben Java Basics - Anfänger-Themen 0
A Cannot make a static reference to the non-static field Java Basics - Anfänger-Themen 6
O Illegal Group Reference Java Basics - Anfänger-Themen 4
L Cannot make a static reference to the non-static method Java Basics - Anfänger-Themen 6
K Variablen Cannot make a static reference to the non-static field time Java Basics - Anfänger-Themen 6
P Compiler-Fehler Cannot make a static reference to the non-static field process Java Basics - Anfänger-Themen 3
C Reference - wird gegen meinen Willen - auf null gesetzt Java Basics - Anfänger-Themen 2
F Mal wieder: Cannot make a static reference to the non-static method Java Basics - Anfänger-Themen 9
F Cannot make a static reference to the non-static method Java Basics - Anfänger-Themen 3
M Reference Java Basics - Anfänger-Themen 2
B Cannot make a static reference...?? Java Basics - Anfänger-Themen 5
B Mal wieder "cannot make a static reference..." Java Basics - Anfänger-Themen 2
N Reference to non-static method Java Basics - Anfänger-Themen 8
C Passing Reference by Value Java Basics - Anfänger-Themen 4
G Wieso ist eine String-Übergabe keine by-reference-Zuweisung? Java Basics - Anfänger-Themen 7
R Cannot make a static reference to the non-static method Java Basics - Anfänger-Themen 5
L [Gelöst] Cannot make a static reference ... Java Basics - Anfänger-Themen 12
N Connot make a static reference. deklarierungsfehler Java Basics - Anfänger-Themen 10
T object reference counts Java Basics - Anfänger-Themen 14
T Cannot make a static reference to the non-static field Java Basics - Anfänger-Themen 8
frau-u Altes Problem: non-static method cannot be reference Java Basics - Anfänger-Themen 7

Ähnliche Java Themen

Neue Themen


Oben