Stack/Heap Frage

b1zarRe

Bekanntes Mitglied
Hi,

kleine Frage zur Identität/Referenz:

Hier der Code:

Java:
        String f="a";
        String g="a";
        System.out.println(f==g); //true!
        g="nicht a";
        System.out.println(f);

Müsste nicht, die Ausgabe "nicht a" ausgeben???
Ich meine ich erzeuge zwei String Variablen f und g. Und da String ein Referenztyp/Klasse ist (und kein elementarer Wert) müsste Java doch auf dem Stack für f ung g den gleichen Zeiger in dem Heap haben mit dem Wert "a". Nun setze ich den Wert auf den g zeigt(welcher ja auch der von f sein sollte) auf:
"nicht a". Und gebe am Ende f aus... Meine Vermutung war, dass nun auch "nicht a" herauskommen muss.. aber es kommt "a" heraus. Woran liegt das!?!?
 
G

Gast2

Gast
Ist doch eigentlich klar?!

Du weißt der Variablen g einen neuen Wert zu. Natürlich zeigt f noch auf seinen alten Wert, warum sollte sich das ändern?
 
K

kaschik

Gast
f referenziert das Objekt "a" aus dem String-Pool und selbiges macht g. Sie referenzieren das selbe Objekt, denn es gibt im String-Pool nur ein "a". Deswegen ist f == g auch true. Trotzdem sind f und g eigenständige Referenzen, was zur Folge hat, dass eine Änderung von f nicht auch g verändert.
 

b1zarRe

Bekanntes Mitglied
Ist die Erklärung nicht viel mehr, dass ich mit
Java:
 g="nicht a";
ein neues StringObjekt erzeugt habe??? Und somit g darauf zeigt und f immernoch auf das alte???
- Das wäre momentan der einzige Weg der mir schlüssig erscheint. - Andererseits finde ich es
halt noch nicht 100% schlüssig, weil dann wäre der Code gleichzusetzen mit:
Java:
 g=new String("nicht a");


Weil:
Java:
public class CallByReference2 {

    public static void gibArrayAus(int[] a) {
        for(int i=0; i<a.length;i++) {
            System.out.print(a[i] + ",");
        }
        System.out.println("");
    }
    
    public static void callByReference(int[] neuesArray, int zahl) {
        neuesArray[0] = zahl;
    }
    
    public static void main(String[] args) {
        
        // Stack: array -> <adr1> Heap: <adr1: {1,2,3}>
        System.out.println("Vorher: ");
        int[] array = {1,2,3};
        gibArrayAus(array);
        System.out.println("");
        
        // Stack: neu=10; array-><adr1> Heap: <adr1: {1,2,3}>
        int neu = 10;
        
        // Methodenausführung
        callByReference(array, neu);
        
        // Nachher
        System.out.println("Nachher: ");
        gibArrayAus(array);
        System.out.println(""); 
    }

Verändert sehr wohl den Inhalt des Arrays "array". Ich dachte daher, dass es bei Strings genauso sein muss, da meines Wissens es in Java zu einem CallByReference kommen kann, wenn man mit nicht elementaren Datentypen arbeitet.(und String ist ja sogesehen nicht elementar wie zb. int, double etc.)
 
G

Gast2

Gast
In Java gibt es nur call-by-value. Ausschließlich. Nichts anderes.
(Erklärung siehe hier: http://www.java-forum.org/allgemeines/4904-call-value-call-reference.html)

Ist die Erklärung nicht viel mehr, dass ich mit [...] ein neues StringObjekt erzeugt habe???
Nein, du hättest auch ein bestehendes Objekt zuweisen können. Der Punkt ist, dass du der Variablen einen neuen "Wert" zuweist.

Was dein Code mit dem oben geschilderten Problem zu tun haben soll verstehe ich nicht ganz.
 
H

hüteüberhüte

Gast
Code:
String s
ist eine Variable, die als Wert eine Referenz speichert. Bei einer Zuweisung wird der Wert, also die Referenz, geändert. Wenn der Variablen eine Referenz auf ein String-Objekt aus dem String-Pool zugewiesen wird, kann es natürlich sein, dass zwei Variablen als Wert die gleiche Referenz haben. Wenn dann allerdings eine neue Zuweisung erfolgt, ändert sich nur die Referenz der einen Variablen. Das beeinflusst nicht die Referenz der anderen Variablen

Sobald du irgendeine Methode mit einem Array aufrufst, liegt ein Objekt vor, dessen Werte/Elemente/Attribute/Variablen, bzw. dessen Zustand, geändert werden kann. Strings sind aber unveränderlich. Trotzdem würde eine Zuweisung an die Array-Variable nichts am ursprünglichen Array ändern
 

b1zarRe

Bekanntes Mitglied
Stimmt, Strings sind unveränderlich... denke das ist es es!!!

Zum anderen Code: Guckt euch den doch mal genauer an.. Ich erzeuge in der Main eine Array mit drei Zahlen. Übergebe
dieses Array einer Methode welches in einem NEUENarray eine zahl darin abändert soll. Gebt nun aber mal das ALTE array aus.... siehe da... es hat sich auch verändert!!
 
G

Gastredner

Gast
Das liegt darin begründet, dass Arrays bei der Übergabe als Parameter wie Objekte behandelt werden. Es wird also die Referenz auf das Array kopiert und nciht das Array selbst, weshalb Änderungen an diesem auch anderswo sichtbar werden.
 
N

new!

Gast
Liest du dir die bereits gegebenen Antworten überhaupt durch? In Java gibt es kein "Call by Reference"!

Übergebe dieses Array einer Methode welches in einem NEUENarray eine zahl darin abändert soll.
Neue Arrays erzeugt man mit new. Kommt das auch nur irgendwo in deinem Code vor?
 
G

Gast2

Gast
@b1zarRe
Ich glaube du hast das noch nicht ganz durchschau. Dass Strings immutable sind hat mit dem verhalten rein gar nichts zu tun. Das funktioniert genau mit jedem anderen Typ.

Dein Beispiel oben hat mit zuletzt geposteten auch rein gar nichts zu tun. Das zweite zeigt nur dass man schnell mal call-by-reference und call-by-value durcheinander bringen kann (was du da scheinbar gemacht hast).
 

b1zarRe

Bekanntes Mitglied
Ich meint damit, dass es zu einen CallByReference EFFEKT kommen kann(siehe Code oben);
Und auch hier ein Verweis: Einführung in die Programmierung - Korrektheit, Zusicherungen, Hoare-Kalkül | Video online

Und deshalb stellte sich mir die Frage, warum es nicht bei Strings genauso funktioniert, da Strings ja kein elementarer
Typ sind... aber denke das liegt damit zusammen, da Strings immutable sind...?

Und ja, ich lese mir die Antworten hier durch... Aber es bringt nichts zu sagen "Gibt es nicht" oder Ähnliches.
Ich will ja verstehen, warum es bei Arrays so klappt und bei Strings anders.
 
N

new!

Gast
Jetzt verstehe ich langsam, worauf du überhaupt hinaus willst.
Und ja, du hast recht, das liegt daran, dass Strings immutable sind. Wenn du statt Strings ein mutable Objekt wie StringBuilder verwendest, kommt es auch zu diesem "call-by-reference-Effekt".

Java:
    public static void callByReference(StringBuilder sb, char replacement) {
        sb.setCharAt(1, replacement);
    }
    
    public static void main(String[] args) {
        StringBuilder string = new StringBuilder("Hase");
        System.out.println(string); // Hase
        callByReference(string, 'o');
        System.out.println(string); // Hose
    }
 
H

hüteüberhüte

Gast
Wenn ihr in diesem Zusammenhang von call-by-reference unterhaltet, kommt es schnell zu Missverständnissen. Die Parameterübergabe ist immer call-by-value. Der Wert einer Referenzvariablen ist eben eine Referenz, die dann kopiert wird. Der Wert eines primitive data types ist eben der Wert an sich, der in diesem Fall kopiert wird

Bei einem Methodenaufruf wird immer der Wert des actual parameters kopiert und an den formal parameter zugewiesen

Hier ist eine Auflistung der Primitiven: Primitive Data Types (The Java™ Tutorials > Learning the Java Language > Language Basics) (Ist nur sehr lang)
 
H

hüteüberhüte

Gast
[OT]Gib ihm doch einen Hinweis xD Aber das hat doch jetzt keine Relevanz für dieses Thema. Edit: Also hat der Link auch nichts mit dem Thema zu tun[/OT]
 
Zuletzt bearbeitet von einem Moderator:

b1zarRe

Bekanntes Mitglied
@new!
Ja genau... Ich finde das Beispiel garnicht so dumm und die Erklärung(ein Video vorher) auch sehr sinnig.
Tipp doch das Beispiel mal ein, anstatt direkt zu behaupten das es quatsch ist... Man sollte kritisch sein/bleiben
und nicht direkt alles niederschmettern.

@hüteüberhüte
was du in dem letzten Post geschrieben hast.... !? Verstehe ich nicht..
 

Mujahiddin

Top Contributor
Ich weiß auch nicht, was es da nicht zu verstehen gibt.
Der Code
Code:
Object o = new Object(){public String toString(){ return "Hallo!";} };
erzeugt ein Objekt und o ZEIGT auf dieses Objekt. Wenn du jetzt eine Methode hast:
Java:
public void boo(Object someObject){
    someObject = new Object(){
        public String toString(){
            return "Tschüss!";
        }
    };
}
und o diesem Objekt übergibst, ändert sich o nicht! o bleibt IMMER gleich, außer du veränderst o direkt. o würde in diesem Fall also weiterhin "Hallo!" ausgeben.

Das gleiche gilt für Strings.
Java:
String s = "Hallo!";
String t = "Hallo!";
t = "Tschüss!";
Wieso sollte sich da
Code:
s
ändern? Du fässt s doch gar nicht an!
 

b1zarRe

Bekanntes Mitglied
Warum ändert sich dann hier der Inhalt von von a indirekt:

Java:
        ArrayList a = new ArrayList();
        ArrayList b = new ArrayList();
        
        a.add("Hallo");
        a.add(100);
        b = a;
        b.add("noch ein neues Element");
        
        Iterator it = a.iterator();
        while(it.hasNext()) {
            System.out.println(it.next());
        }

- Korrekt, weil b(genauso wie a) auf den gleichen Wert im Heap zeigen. Und nun addiert b etwas
zu diesem 'Bereich' im Heap dazu. Also hat auch a diesen dazu bekommen. Bei elementaren Werten passiert
dieses nicht, weil die keinen "Zeiger" auf den Heap haben. Bei nicht elementaren Werten(Array,Objekte, ArrayListen etc.)
hingegen schon... und genau DESHALB habe ich nun gefragt, warum es bei Strings wohl nicht so ist und diese
sich ähnlich wie elementare Datentypen verhalten.

Das liegt wohl daran das diese immutable sind... also sorry, aber ich finde das alles nicht so trivial!! Und habe langsam
die Vermutung das einige von euch das auch nicht wissen, aber direkt abklatschen mit "nein soetwas gibst in java garnicht...."
 
G

Gast2

Gast
Du beschreibst einen komplett anderen Sachverhalt als Mujahiddin ;)

Mujahiddin hat dir gezeigt dass es in Java kein call-by-referrnce gibt (das ändern der (kopierten) Referenz hat keine Auswirkungen auf den Aufrufer).

Du hingegen hast "nur" gezeigt dass wenn zwei Variablen auf das gleiche Objekt zeigen, beide das selbe Objekt verändern, was ja eigentlich auch klar und logisch ist. Wäre das nicht so würde man sich ganz schön schwer tun beim programmieren :p

Wie oben schon erwähnt, mit immutable und nicht-immutable bist du da aufm falschen Dampfer, das hat damit wenig zu tun.
 

b1zarRe

Bekanntes Mitglied
Und warum hat

Java:
public static void main(String[] args) {

       ArrayList a = new ArrayList();
        a.add("Hallo");
        a.add(100);
        
        machWas(a);
        
        Iterator it = a.iterator();
        while(it.hasNext()) {
            System.out.println(it.next()); //Output: Hallo, 100, ganz neu ---> Würde man nun die ganze Sache mit elementaren Typen, wie zb. int anstelle ArrayList realisieren, hätte die Methode KEINE Änderungen für das ursprüungliche int gemacht !!!!!!
        }
    }
    
    public static void machWas(ArrayList neu) {
        neu.add("ganz neu");
    }
}

die kopierte Referenz sehr wohl Auswirkung auf den Aufrufer???
 
Zuletzt bearbeitet:
G

Gast2

Gast
Was genau meinst du denn mit "es"?

Bei der ArrayList änderst du mit dem add die "inneren Daten" der ArrayList instanz. Einen String kannst du nicht ändern. Deshalb ist das Beispiel auf Strings nicht übertragbar.

Könnte man Strings ändern, bspw. mit einer setCharAt() Methode könnte man das Beispiel auch 1 zu 1 auf Strings übertragen.
 

b1zarRe

Bekanntes Mitglied
Jawohl... und deshalb zitiere ich dich nochmal:
"Wie oben schon erwähnt, mit immutable und nicht-immutable bist du da aufm falschen Dampfer, das hat damit wenig zu tun."
Also, hat dies sehr wohl was mit immutable(und in den anderen Fällen ob elementarer Datenyp bzw. nicht elemntar) zu tun ;)
- Mehr wollte ich nicht wissen... habe das ganze als CallByReference Effekt benannt, weil der Prof. das in der Vorlesung auch so benannt hatte.... Und muss sagen, das mir meine Codes nun soweit klar sind.

Was mir dagegen nichtmehr ganz so klar ist, ist was nun genau CallByReference ist, wenn es das nicht ist, was ich genannt habe.
Der Link "CallByValue/CallByReference" habe ich mir schon zugemüte geführt... bringt mich allerdings nicht wirklich weiter... jendefalls nicht 100 Prozent:

Ein Beispiel aus dem Link

Java:
public static void main(String[] args){
		Integer i = new Integer(1);
		Integer j = new Integer(2);
		System.out.println(i + " " + j);
		swap(i,j);
		System.out.println(i + " " + j);
	}
	
	public static void swap(Integer i, Integer j) {
		Integer tmp = i;
		i = j;
		j = tmp;
	}

Hier wird nun gesagt, dass beides mal 1 2 herauskommt. Also es kein CallByReference gibt(!= einer ähnlichen Umsetzung in C),
ABER: kann man das überhaupt so vergleichen??? Integer ist nämlich der Wrapper für ein int.. Also eine Hülle welche auch nur ein int in sich trägt. Meiner Meinung nach wird genau DESHALB zweimal 1 2 ausgegeben. Man möge das Beispiel doch mit ArrayListen oder Arrays machen... ich glaube dann sieht das ganze anders aus...... - deshalb ist dieses FAQ hier aus dem Forum entweder falsch oder ich steige da noch nicht 100 Pro durch.
 
G

Gast2

Gast
Jawohl... und deshalb zitiere ich dich nochmal:
"Wie oben schon erwähnt, mit immutable und nicht-immutable bist du da aufm falschen Dampfer, das hat damit wenig zu tun."
Also, hat dies sehr wohl was mit immutable(und in den anderen Fällen ob elementarer Datenyp bzw. nicht elemntar) zu tun
Nur weil Äpfel rund sind, heißt das nicht dass alles was rund ist nen Apfel sein muss.

Zu deinem Beispiel. Probiers einfach mit irgend einer beliebigen Klasse, erstelle dir selbst eine Klasse. Du wirst immer das selbe verhalten feststellen, eben weil es in Java nunmal kein call-by-reference gibt ;)

[...] oder ich steige da noch nicht 100 Pro durch
Ich tippe auf diesen Fall :)
 
H

hüteüberhüte

Gast
Edit: Durch eine Zuweisung (weil call-by-value) lässt sich kein Objekt ändern. Ich hab früher in Grundlagenvorlesung gelernt, eine Zuweisung weist einer Variablen einen Wert zu, nicht mehr, nicht weniger. Und der Wert ist bei einer Referenzvariablen eine Referenz

Edit2: Siehe nächsten Beitrag (Sry, Doppelpost)
 
Zuletzt bearbeitet von einem Moderator:
H

hüteüberhüte

Gast
Ok, in der JLS steht etwas darüber: Types, Values, and Variables
Method parameters (§8.4.1) name argument values passed to a method. For every parameter declared in a method declaration, a new parameter variable is created each time that method is invoked (§15.12). The new variable is initialized with the corresponding argument value from the method invocation. The method parameter effectively ceases to exist when the execution of the body of the method is complete.

Also die Variable (der formale Parameter) wird mit dem Wert des Arguments initialisiert

Bin mir sicher, es wird auch noch etwas mehr darüber stehen. Explizit "call-by-value" bzw. "pass-by-value" habe ich jetzt nicht gefunden, aber es wird genau dieser Vorgang beschrieben
 

AngryDeveloper

Bekanntes Mitglied
ABER: kann man das überhaupt so vergleichen??? Integer ist nämlich der Wrapper für ein int.. Also eine Hülle welche auch nur ein int in sich trägt. Meiner Meinung nach wird genau DESHALB zweimal 1 2 ausgegeben. Man möge das Beispiel doch mit ArrayListen oder Arrays machen... ich glaube dann sieht das ganze anders aus...... - deshalb ist dieses FAQ hier aus dem Forum entweder falsch oder ich steige da noch nicht 100 Pro durch.

Dann mach das Beispiel doch mit z.B. ArrayList. Ist doch Jacke wie Hose:
Java:
public static void main(String[] args){
    ArrayList i = new ArrayList();
    i.add("1");
    ArrayList j = new ArrayList();
    j.add("2");
    System.out.println(i.get(0) + " " + j.get(0));
    swap(i,j);
    System.out.println(i.get(0) + " " + j.get(0));
}
	
public static void swap(ArrayList i, ArrayList j) {
    ArrayList tmp = i;
    i = j;
    j = tmp;
}
Ausgabe ist beide male 1 2

Wenn du das wirklich swappen wollen würdest, dann müsstest du das erste Element in der Datenstruktur austauschen. Dies ist dann aber ein ganz anderer Fall, weil da etwas ganz anderes passiert.

Java -> nur Call by Value
Java is Pass-by-Value, Dammit! - Scott Stanchfield
 

b1zarRe

Bekanntes Mitglied
Du hast recht: Beide mal 1 2 ... Aber warum??? Kann mir das jemand evtl. erklären und sagen, was Da schritt für schritt mit Stack/Heap passiert???

Java:
    int[] i = {1};
    System.out.println(i[0]);
    change(i);
    System.out.println(i[0]);
}
    
    public static void change(int[] i) {
        i[0]=10;
    }
}
Warum wird denn hier das anfängliche Array verändert?! Müsste da bei
der 2. Ausgabe dann nicht auch "nur" 1 herauskommen?!?!
 
G

Gast2

Gast
Lass doch den Stack einfach mal Stack sein. Es reicht wenn du dir vorstellst dass es irgendwo ein Objekt gibt und irgendwo ander eine Variable die auf dieses Objekt zeigt.

Vergleich mal doch die beiden kritischen Stücke:
Java:
public static void swap(Integer i, Integer j) {
    Integer tmp = i;
    i = j;
    j = tmp;
}
und
Java:
public static void change(int[] i) {
     i[0]=10;
}
Beim ersten mal tauschst du nur die Objekte aus auf die i bzw. j zeigen. Das hat auf den Aufrufer aber keine Auswirkungen.
Beim zweiten mal hast du zwei Referenzen die auf dein Array (Objekt) zeigen. Einmal die Referenz des Aufrufers, und zum anderen die Referenz in der Methode. Jetzt änderst du das Objekt in der Methode, das bekommt der andere natürlich mit.
 

AngryDeveloper

Bekanntes Mitglied
Weil das 2 grundlegend verschiedene Dinge sind. Siehe wiederum:
Java:
public static void main(String[] args) {
    int[] i = {1};
    int[] j = {2};
    System.out.println(i[0] + " " + j[0]);
    swap(i, j);
    System.out.println(i[0] + " " + j[0]);
}
    
public static void swap(int[] i, int[] j) {
    int[] tmp = i;
    i = j;
    j = tmp;
}

Bei dem einen veränderst du den Inhalt eines Objekts (das Objekt ist in diesem Fall das Array, der Inhalt ist der Wert an Index 0). Bei Arrays wird der Zeiger übergeben und keine komplette Kopie des Arrays.

Bei dem anderen veränderst du die Adresse auf die die Variable zeigt. Dieser Zeiger wird allerdings bei der Übergabe kopiert. Weißt du dieser Kopie einen neuen Zeiger/Adresse zu, ändert sich ja nicht der Zeiger der Variable die du übergeben hast.

Java macht es hierbei wie C und den Pointern (*): Call by Value.
Nicht wie C++ bei Referenzen (&): Call by Reference.
 

b1zarRe

Bekanntes Mitglied
Okay danke...
glaube mein Fehler war zu denken, dass "=" das selbe macht in jeder Situation, wobei es klar ist, dass

1) int a = 10;

was anderes ist als

2) ArrayList a = new ArrayList();
ArrayList b = a;

Beim ersten wieder der Wert verändert und beim zweiten der Zeiger, korrekt?
 

andiv

Bekanntes Mitglied
Um den Unterschied zwischen Call by Value und Call by Reference zu verstehen, kann es sich lohnen eine Sprache zu betrachten, die auch wirklich beide Varianten unterstützt. Ich wähle dazu C++:

Java:
// [1] Normale Variable vom Typ "Foo" mit Namen "var"
Foo var;
// es wird automatisch der Konstruktor von Foo aufgerufen

// [2] Zeiger auf eine Variable vom Typ "Foo" mit dem Namen "ptr"
Foo* ptr = &var;
// dem Zeiger muss die Adresse einer Variable vom Typ "Foo" zugewiesen werden

// [3] Zeiger auf einen Zeiger auf eine Variable vom Typ "Foo" mit Namen "dblptr"
Foo** dblptr = &ptr;
// dem Zeiger muss die Adresse eines Zeigers auf eine Variable vom Typ "Foo" zugewiesen werden

// [4] Referenz auf eine Variable vom Typ "Foo" mit Namen "ref"
Foo& ref = var;
// der Referenz muss eine Variable vom Typ "Foo" zugewiesen werden

Das besondere an der Referenz ist, dass "ref" ein Alias für "var" ist. Ob man ref oder var schreibt ist egal, beides meint die gleiche Variable. Im Gegensatz dazu ist der Wert von "ptr" die Adresse von "var" und damit ein anderer als der Wert von "var".

Java:
// [5] Beim Aufruf von "callByValue" werden die Variablen kopiert
void callByValue(Foo var1, Foo var2) {
    Foo tmp = var1;
    var1 = var2;
    var2 = tmp;
}

// "var1" und "var2" sind nach Aufruf der Funktion unverändert
Foo var1;
Foo var2;
callByValue(var1, var2);

// [6] Beim Aufruf von "callByValue2" werden die Zeiger kopiert
void callByValue2(Foo* ptr1, Foo* ptr2) {
    Foo* tmp = ptr1;
    ptr1 = ptr2;
    ptr2 = tmp;
}

// "ptr1" und "ptr2" sind nach Aufruf der Funktion unverändert
Foo ptr1 = &var1;
Foo ptr2 = &var2;
callByValue(ptr1, ptr2);

// [7] Beim Aufruf von "callByValue3" werden die Zeiger kopiert, aber es werden nicht die Kopien verändert, sondern die Variablen auf die sie zeigen
void callByValue3(Foo* ptr1, Foo* ptr2) {
    Foo tmp = *ptr1;
    *ptr1 = *ptr2;
    *ptr2 = &tmp;
}

// "ptr1" und "ptr2" sind nach Aufruf der Funktion unverändert, aber die Variablen auf die sie zeigen, also "var1" und "var2" wurden verändert
callByValue(ptr1, ptr2);

// [8] Beim Aufruf von "callByReference" werden die Variablen nicht kopiert! "ref1" ist ein Alias für die übergebene Variable
void callByReference(Foo& ref1, Foo& ref2) {
   Foo tmp = ref1;
   ref1 = ref2;
   ref2 = tmp;
}

// "var1" und "var" sind nach Aufruf der Funktion verändert
callByReference(var1, var2);

Wie verhält sich das ganze nun in Java?
Ist Foo einer der Typen byte, short, int, long, char, float oder double, dann entspricht das dem Fall [1] in C++.
Ist Foo vom Typ Object oder einer anderen Klasse wie String, int[] oder ArrayList, dann entspricht das dem Fall [2] in C++ und wir haben es die ganze Zeit mit einem Zeiger auf eine Variable zu tun. Den * braucht man in Java nicht, da durch den Typ der Variable direkt klar ist ob wir einen Zeiger haben oder nicht. Die Möglichkeit von Zeigern auf Zeiger oder höheres [3] gibt es genausowenig wie richtige Referenzen [4] die als Alias wirken.

Java:
// [9] Beim Aufruf von "callByValue" werden die Variablen kopiert
void callByValue(int var1, int var2) {
    int tmp = var1;
    var1 = var2;
    var2 = tmp;
}

// "var1" und "var2" sind nach Aufruf der Funktion unverändert
int var1;
int var2;
callbyValue(var1, var2);

// [10] Beim Aufruf von "callByValue2" werden die Zeiger kopiert
void callByValue2(int[] ptr1, int[] ptr2) {
    int[] tmp = ptr1;
    ptr1 = ptr2;
    ptr2 = tmp;
}

// "ptr1" und "ptr2" sind nach Aufruf der Funktion unverändert
int[] ptr1 = {1};
int[] ptr2 = {2};
callByValue2(ptr1, ptr2}

// [11] Beim Aufruf von "callByValue3" werden die Zeiger kopiert, aber es werden nicht die Kopien verändert, sondern die Variablen auf die sie zeigen
void callByValue3(int[] ptr1, int[] ptr2) {
    int tmp = ptr1[0];
    ptr1[0] = ptr2[0];
    ptr2[0] = tmp;
}

// "ptr1" und "ptr2" zeigen nach Aufruf der Funktion weiter auf die gleichen Objekte, aber der Inhalt der Objekte wurde verändert
callByValue(ptr1, ptr2);

Der Fall [9] in Java entspricht genau dem Fall [5] in C++.
Der Fall [10] in Java entspricht dem Fall [6] in C++, um den Zeiger selbst zu verändern müsste man entweder einen Zeiger auf einen Zeiger übergeben (call-by-value-Variante) oder eine Referenz auf einen Zeiger (call-by-reference-Variante), in Java ist so etwas nicht möglich.
Der Fall [11] entspricht dem Fall [7] in C++, wir lassen uns einen Zeiger übergeben und verändern das Objekt auf das er zeigt. Diese Wirkung ist auch von außen sichtbar.
Etwas analoges zu Fall [8] gibt es in Java nicht, denn Java kennt kein "call-by-reference".

Was ist das besondere an "immutable" Objekten in Java? Variante [10] ist bekanntlich wirkungslos und Variante [11] unmöglich, da das Objekt auf das "ptr" zeigt keine Möglichkeit zur Veränderung bietet. Der Außenstehende hat also das Gefühl er hätte es mit Variante [9] zu tun.

Was soll nun der "call-by-reference"-Effekt sein? Wenn Variante [11] mit einem "mutable"-Objekt verwendet wird, dann ist nach außen eine Wirkung sichtbar. Den Außenstehenden erinnert der Funktionsaufruf nun an Variante [8] aus C++ (richtiges Call by Reference), in Wahrheit haben wir es aber mit Fall [7] aus C++ zu tun (Call by Value).

Die Verständnisprobleme sind also nur deshalb da, weil Java nicht durch zusätzliche Syntax deutlich macht, wann wir mit normalen Variablen und wann mit Zeigern herum hantieren.
 
H

hüteüberhüte

Gast
Okay danke...
glaube mein Fehler war zu denken, dass "=" das selbe macht in jeder Situation, wobei es klar ist, dass

1) int a = 10;

was anderes ist als

2) ArrayList a = new ArrayList();
ArrayList b = a;

Beim ersten wieder der Wert verändert und beim zweiten der Zeiger, korrekt?

Ja, das ist korrekt. In Java gibt es aber kein Alias, weil immer ein Kopie des Werts erstellt wird und den Parametern zugewiesen wird. Außerdem gibt es keine Zeiger/Referenzen auf selbige
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
M Frage zu Stack und Heap Java Basics - Anfänger-Themen 1
V Ist Off-Heap-Speicher dasselbe wie Stack-Speicher? Java Basics - Anfänger-Themen 2
KogoroMori21 Stack und Heap Speicher Java Basics - Anfänger-Themen 1
F speicherort stack oder heap Java Basics - Anfänger-Themen 1
P Stack, Heap Java Basics - Anfänger-Themen 13
J Array von Objekten, wie schauts im Heap / Stack aus ? Java Basics - Anfänger-Themen 7
J Morgen Java-Klausur. Stack, Heap, Method-Area Java Basics - Anfänger-Themen 2
A stack Java Basics - Anfänger-Themen 14
Proxy Stack erweitern mit neuem Array falls der alte voll ist!? Java Basics - Anfänger-Themen 5
izoards Stack... Java Basics - Anfänger-Themen 17
Csircc Rekursive Methode Stack Overflow Java Basics - Anfänger-Themen 10
B Zahlenfolge von Queue in Stack Java Basics - Anfänger-Themen 29
L Stack bilden, push und pop Java Basics - Anfänger-Themen 16
G Stack und Queue Arbeitsblatt Java Basics - Anfänger-Themen 3
G Stack programmieren Java Basics - Anfänger-Themen 6
Z Datentypen Stack based calculator Java Basics - Anfänger-Themen 8
S Rekursiven Stack Java Basics - Anfänger-Themen 6
Curtis_MC Collections Zufälliges Element aus Stack Java Basics - Anfänger-Themen 2
D Queue vs. Stack Java Basics - Anfänger-Themen 6
D Erste Schritte Stack im Rollenspiel Java Basics - Anfänger-Themen 76
J Stack mit Benutzereingabe Java Basics - Anfänger-Themen 17
J Liste,Queue,Stack sortieren Java Basics - Anfänger-Themen 2
C Stack und Queue in Aktion (Bitte Hilfe für die Klausur) Java Basics - Anfänger-Themen 7
S Sequenz von Zahlen bei einem Stack möglich oder nicht möglich? Java Basics - Anfänger-Themen 5
E Stack vs Queue - Gemeinsamkeiten / Unterschiede Java Basics - Anfänger-Themen 7
C Laufzeit von Stack Operation Java Basics - Anfänger-Themen 5
4 Stack over flow bei rekursiver Tiefensuche Java Basics - Anfänger-Themen 5
J Quicksort mit Stack Java Basics - Anfänger-Themen 4
A Anzahl der Elemente in einem Stack wiedergeben Java Basics - Anfänger-Themen 3
T Stack Overflow - Rekursive Fibonacci Java Basics - Anfänger-Themen 10
K Tiefen- und Breitensuche beim Baum durch Stack und Warteschlange Java Basics - Anfänger-Themen 1
L Liste mittels Stack implementieren Java Basics - Anfänger-Themen 0
A Stack programmieren -> Unklarheiten Java Basics - Anfänger-Themen 1
C Stack - listenbasierte Implementierung Java Basics - Anfänger-Themen 4
L Mit rekursiven Aufrufen einen Stack emulieren Java Basics - Anfänger-Themen 1
T Frage zu Java Stack Java Basics - Anfänger-Themen 5
D Stack-Objekt - LIFO - wait(); notify(); Java Basics - Anfänger-Themen 0
Farbenfroh Suche Übungsaufgaben: BinaryTree, Stack Java Basics - Anfänger-Themen 0
D Aufgabe: Stack mit Iterator Java Basics - Anfänger-Themen 8
X Stack mit Oberklasse, wieso funktioniert es nicht? Java Basics - Anfänger-Themen 8
K Probleme mit stack Java Basics - Anfänger-Themen 7
K Wofür wird heute noch die Stack Klasse in Java genutzt Java Basics - Anfänger-Themen 4
F Rekursion Tiefensuch-Problem - Stack Overflow Java Basics - Anfänger-Themen 9
P LinkedList - Stack ... grundlegende Frage Java Basics - Anfänger-Themen 5
B Stack in eine verkettete Liste pushen Java Basics - Anfänger-Themen 4
J OOP Warum braucht man den Stack Java Basics - Anfänger-Themen 3
B Queue mit Daten aus einem Stack füllen Java Basics - Anfänger-Themen 21
G Stack invertieren Java Basics - Anfänger-Themen 3
H Pseudo-Stack (char[] stackArray) mit Zeichen aus einer .txt-Datei befüllen Java Basics - Anfänger-Themen 5
S Stack Problem mit Objekt Java Basics - Anfänger-Themen 2
X String mit String von Objekt im Stack vergleichen? Java Basics - Anfänger-Themen 14
D Stack auslesen mit pop Java Basics - Anfänger-Themen 2
S Stack als verkettete liste/ toString methode Java Basics - Anfänger-Themen 3
S Exceptions bei push/pop in Stack Java Basics - Anfänger-Themen 8
S Eigene Stack Klasse Java Basics - Anfänger-Themen 26
S Stack: Klasseninvariante Java Basics - Anfänger-Themen 4
L OOP Wrapper Klassen - Stack-Aufgabe Java Basics - Anfänger-Themen 2
M Frage zu Stack Java Basics - Anfänger-Themen 3
D Problem mit Set, Stack und Random Java Basics - Anfänger-Themen 2
O Stack Implementierung als verkettete Liste Java Basics - Anfänger-Themen 8
T Probleme bei einen Stack der über drei Dateien funktionieren soll Java Basics - Anfänger-Themen 5
V java.util.Stack Java Basics - Anfänger-Themen 9
K Stack und immer gleiches Objekt Java Basics - Anfänger-Themen 11
kulturfenster Stack / Queue Implementationen Java Basics - Anfänger-Themen 11
S Stack einlesen. Java Basics - Anfänger-Themen 2
E Stack kann nicht implimentiert werden Java Basics - Anfänger-Themen 11
E Eigene Stack Klasse schreiben Java Basics - Anfänger-Themen 12
J Stack Java Basics - Anfänger-Themen 3
K min-int-Wert in'nem Stack Java Basics - Anfänger-Themen 8
L Stack UpnRechner Java Basics - Anfänger-Themen 4
B Stack mit Bildern füllen Java Basics - Anfänger-Themen 2
B Stack mit Strings in zufälliger Reihenfolge füllen Java Basics - Anfänger-Themen 4
J Stack, der Integer-Zahlen enthält Java Basics - Anfänger-Themen 3
K Array Stack Java Basics - Anfänger-Themen 6
O Stack-Klasse Java Basics - Anfänger-Themen 7
S Stack mit Arrays Java Basics - Anfänger-Themen 3
T generischer stack Java Basics - Anfänger-Themen 3
Z Keller/Stack Problem Java Basics - Anfänger-Themen 11
H Stack und Queue Java Basics - Anfänger-Themen 6
M Stack SetValTop Java Basics - Anfänger-Themen 6
G Die Klasse Stack selber schreiben. Java Basics - Anfänger-Themen 2
F Klammertest mit Stack implementieren Java Basics - Anfänger-Themen 5
X Stack Java Basics - Anfänger-Themen 14
H Unterschied zwischen Stack und Array Java Basics - Anfänger-Themen 3
F MergeSort iterativ mit Hilfe von Stack Java Basics - Anfänger-Themen 5
S stack Java Basics - Anfänger-Themen 3
S Stack invertieren Java Basics - Anfänger-Themen 14
S Stack-Operationen Java Basics - Anfänger-Themen 59
S Stack.pop() wie genau funktioniert das? Java Basics - Anfänger-Themen 3
A Stack, Frage zur Methode push Java Basics - Anfänger-Themen 4
C Anzahl der Elemente auf einem Stack Java Basics - Anfänger-Themen 4
D Stack chaos Java Basics - Anfänger-Themen 2
megachucky kleines problem mit nem STACK Java Basics - Anfänger-Themen 8
I Stack ist auf einmal empty Java Basics - Anfänger-Themen 3
R Beispiele für Stack & Visualisierung Java Basics - Anfänger-Themen 2
R Stack: Wieso funktioiert das? Java Basics - Anfänger-Themen 2
B eine kleine leichte aufgabe mit einem stack programmieren Java Basics - Anfänger-Themen 2
N Stack-Probleme Java Basics - Anfänger-Themen 2
K Stack Overflow Java Basics - Anfänger-Themen 2
S Java Client-je nach Heap Size Größe startet Applikation oder nicht Java Basics - Anfänger-Themen 4

Ähnliche Java Themen

Neue Themen


Oben