Arbeitet Java mit call by value-return?
-
Arbeitet Java mit call by value-return?
class Auto { Auto(int AnzahlReifen) { m_AnzahlReifen = AnzahlReifen; } public int m_AnzahlReifen; } public class Main { public static void main(String[] args) { Auto MeinAuto = new Auto(4); foo(MeinAuto); System.out.print("r: " + MeinAuto.m_AnzahlReifen); // gibt 4 aus } static void foo(Auto irgendeinAuto) { irgendeinAuto = new Auto(6); } }
Es gibt Tage da fällt man vom Glauben ab
-
Eigentlich werden nur die eingebauten Typen per value übergeben, Objekt-Instanzen immer per Referenz. Wundere mich aber gerade auch über dein Beispiel...
//Edit: Grad gefunden: http://forum.java.sun.com/thread.jspa?threadID=544997&tstart=15
-
How does pass-by-value work with references?
Way too many people say "Java passes primitive by value and objects by reference". This is not the way it should be stated. Java passes everything by value. With primitives, you get a copy of the contents. With references you get a copy of the contents.
But what is the contents of a reference?
The remote control. The means to control / access the object.
When you pass an object reference into a method, you are passing a COPY of the REFERENCE. A clone of the remote control. The object is still sitting out there, waiting for someone to use a remote.The object doesn't care how many remotes are "programmed" to control it. Only the garbage collector cares (and you, the programmer).
So when you say:
Cat A = new Cat();
doStuff(A);void doStuff(Cat {
// use B in some way
}There is still just ONE Cat object. But now TWO remote controls (references) can access that same Cat object.
So now, anything that B does to the Cat, will affect the Cat that A refers to, but it won't affect the A cup!
You can change the Cat, using your new B reference (copied directly from A), but you can't change A.
What the heck does that mean?
You can change the object A refers to, but you can't take the A reference variable and do something to it -- like redirect it to reference a different object, or null.
So if you change the B reference (not the Cat object B refers to, but the B reference itself) you don't change A. And the opposite is true.
So...
Cat A = new Cat();
doStuff(A);void doStuff(Cat {
B = new Cat(); //did NOT affect the A reference
}Doing this simply "points" B to control a different object. A is still happy.
So repeat after me:
Java is pass-by-value.
(OK, once again... with feeling.)
Java is pass-by-value.
For primitives, you pass a copy of the actual value.
For references to objects, you pass a copy of the reference (the remote control).
You never pass the object. All objects are stored on the heap. Always.
Now go have an extra big cup of coffee and write some code.
ab damit in die FAQ
-
Was bitte soll den call by value-return sein. Ich kenne nur call by value. Für das was du da vor hast würde man in C++ einen pointer auf nen pointer verwenden, aber so was gibt es in java nicht.
-
Es gibt folgende Paramterübergabemechanismen
- Wertübergabe (call by value)
- Referenzübergabe (call by reference)
- Wert-Ergebnis-Übergabe (call by value-return)
- Namensübergabe (call by name)Wert-Ergebnis-Übergabe
- An das Unterprogramm (Funktion, Prozedur) wird bei Aufruf der Wert des aktuellen Parameters übergeben == Kopie des Wertes
- Bei Verlassen wird der letzte Wert des formalen Parameters an den Speicherplatz des aktuellen Paramters zurückkopiert.Anscheinend ist bei Java wirklich alles Call by Value
-
Vertexwahn schrieb:
Anscheinend ist bei Java wirklich alles Call by Value
Ne. Ich habs jetzt nicht ausprobiert aber das sollte call by reference sein und so auch 6 ausgeben.
class Auto { Auto(int AnzahlReifen) { m_AnzahlReifen = AnzahlReifen; } public int m_AnzahlReifen; } public class Main { public static void main(String[] args) { Auto MeinAuto = new Auto(4); foo(MeinAuto); System.out.print("r: " + MeinAuto.m_AnzahlReifen); // gibt 4 aus } static void foo(Auto irgendeinAuto) { irgendeinAuto.m_AnzahlReifen = 6; } }
-
Ahh.... schrieb:
Ne. Ich habs jetzt nicht ausprobiert aber das sollte call by reference sein und so auch 6 ausgeben.
lol - meinst du wirklich ich hätte das einfach so gepostet das es 4 ausgibt und es nicht einmal durch den Compiler laufen lassen
lese die Seite:
http://www.javaranch.com/campfire/StoryPassBy.jsp
und werde ein besserer Mensch/Java Programmierer
-
Vertexwahn schrieb:
Ahh.... schrieb:
Ne. Ich habs jetzt nicht ausprobiert aber das sollte call by reference sein und so auch 6 ausgeben.
lol - meinst du wirklich ich hätte das einfach so gepostet das es 4 ausgibt und es nicht einmal durch den Compiler laufen lassen
lese die Seite:
http://www.javaranch.com/campfire/StoryPassBy.jsp
und werde ein besserer Mensch/Java ProgrammiererSchau mal den Code bei mir genau an. Du kannst ihn ja nochmal durch den compiler "laufen" lassen.
-
aso du meinst deinen Code - ist schon klar - wollte nur sagen - nur weil man eine Referenz an einen Funktion übergibt ist das noch lange nicht Call by reference
-
C# und Übergabemechanismen: call by value vs. call by reference
Motivation
Wissen Sie wie call by value und call by reference in C# funktioniert? Was…? Sie sind ein alter C++ Programmierer und in C# ist doch alles genau so? Hier ein Motivationsbeispiel:
using System; class Auto { public Auto(int AnzahlReifen) { m_AnzahlReifen = AnzahlReifen; } public int m_AnzahlReifen; } public class MyApp { public static void Main() { Auto MeinAuto = new Auto(4); foo(MeinAuto); System.Console.WriteLine(MeinAuto.m_AnzahlReifen); // gibt 4 aus } static void foo(Auto irgendeinAuto) { irgendeinAuto = new Auto(6); } }
Wenn sie jetzt verwundert vor dem Bildschirm hocken und sich fragen warum obiges Programm die Zahl 4 ausgibt und nicht die Zahl 6, dann sind Sie ein Leser meine Zielgruppe. Falls nicht, werden sie im folgendem auch nichts neues mehr erfahren.
Alles call by value
Um es kurz zu machen: Parameterübergabe in C# erfolgt implizit immer in Form von call by value.
Jetzt fragen Sie sich sicherlich warum folgendes geht und warum das nicht call by reference ist:
using System; class Auto { public Auto(int AnzahlReifen) { m_AnzahlReifen = AnzahlReifen; } public int m_AnzahlReifen; } public class MyMain { public static void Main() { Auto MeinAuto = new Auto(4); foo(MeinAuto); System.Console.WriteLine(MeinAuto.m_AnzahlReifen); // gibt 6 aus } static void foo(Auto irgendeinAuto) { irgendeinAuto.m_AnzahlReifen = 6; } }
Die Erklärung ist ganz einfach. Übergibt man eine Referenz an eine Methode, so wird ihr Inhalt kopiert. Was ist der Inhalt eine Referenz? Der Inhalt einer Referenz ist nur ein Verweis, der angibt, wo sich das zugehörige Objekt befindet. Wenn man also eine Referenz an eine Methode übergibt wird eine Kopie der Referenz an die Funktion übergeben.
Auto A = new Auto(); doSomething(A); void doSomething(Auto B) { // mache etwas mit B }
Bei dem Aufruf der Methode doSomething wird eine zweite Referenz angelegt, die auf das Objekt Auto verweist. Verändert die Referenz B das Objekt so wirkt sich dies auf das Auto Objekt aus.
Man kann in der Methode doSomething das Auto Objekt verändern, aber nicht die Referenz A.
Sehen Sie sich jetzt noch einmal das Motivationsbeispiel an und stellen Sie fest warum 4 und nicht 6 ausgegeben wird.
Man kann in der Methode doSomething nicht die Referenz A auf ein anderes Objekt zeigen lassen, da man nur mit einer Kopie arbeitet.
Auto A = new Auto(); doSomething(A); void doSomething(Auto B) { B = new Aute(); // beeinflusst nicht die Referenz A }
Es bleibt festzuhalten: C# arbeitet mit call-by-value, auch wenn man Referenzen übergibt. Bei Java ist es genau so.
Call by refernece
In C# ist auch call by reference bei der Paramterübergabe möglich. Dabei wird vor jedem Parameter der per call by reference übergeben werden soll das Schlüsselwort ref gestellt:
using System; class Auto { public Auto(int AnzahlReifen) { m_AnzahlReifen = AnzahlReifen; } public int m_AnzahlReifen; } public class MyMain { public static void Main() { Auto MeinAuto = new Auto(4); foo(ref MeinAuto); System.Console.WriteLine(MeinAuto.m_AnzahlReifen); // gibt 6 aus } static void foo(ref Auto irgendeinAuto) { irgendeinAuto = new Auto(6); } }
Schlusswort
In C# gibt es auch noch das Schlüsselwort out bei der Paramterübergabe. Wer Interesse daran hat kann ja einmal danach per google.de suchen. Ich hoffe der Unterschied zwischen call by value und call by reference ist klar geworden.