Java - Call by value <-> Call by reference

mrbela

Bekanntes Mitglied
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):

Java:
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:
Code:
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?
 
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.
 
Wie schon in dem Thread von bygones zitiert ist hier der Abschnitt wichtig:

Code:
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:

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:

Java:
 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 😉 🙂
 
Zuletzt bearbeitet:
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. 🙁
 
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?!
 
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.
 
in deinem Beispiel geht es z.b. auch nicht den Vektor einfach zu ändern:

Java:
 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 😉 🙂

Falsch! Nur v=null geht nicht 😉
 
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!
 
Also es erfolgt ein call by value, da eine Kopie erstellt wird.

Vorsicht, es wird keine Kopie erstellt. Beispiel:
Java:
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:
Java:
public void doSomethingWithMyObject(MyObject myo) {
    myo.toString();
    //...
}
 
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 😉.
 

Zurück
Oben