PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Java: Lebensdauer eines funktionswertes


ooAlbert
2007-03-09, 13:49:24
Hi,

ich hab mal eine frage wie lange ein ausgabewert einer Javafunktion "lebt", bzw. wie lang der wert abrufbar ist.

mfg

Trap
2007-03-09, 13:58:31
Ich versteh die Frage nicht. Die einfachste Abstraktion zur Objektlebensdauern in Java ist: alles lebt ewig. Die tatsächliche Implementierung verbraucht eventuell weniger Speicher, verhält sich aber sonst gleich.

EcHo
2007-03-09, 13:59:14
Kannst du die Frage noch ein einmal formulieren? Ich verstehe sie ehrlich gesagt nicht.
Meine Antwort wäre im Moment: "Ist definiert durch den umgebenen Block".

Monger
2007-03-09, 14:08:34
Ich versteh die Frage nicht. Die einfachste Abstraktion zur Objektlebensdauern in Java ist: alles lebt ewig. Die tatsächliche Implementierung eventuell verbraucht weniger Speicher, verhält sich aber sonst gleich.
Das ist die beste Erklärung die man wohl geben kann.
In Java ist alles (naja, fast alles) ein Objekt - also auch die Rückgabewerte. Ein Objekt wird im Moment der Instanziierung geboren, und lebt eine ungewisse Zeit - definitiv aber mindestens so lange wie man es noch kennt.

Ob ein Objekt jetzt übergeben, zurückgegeben, grün angestrichen oder auf den Kopf gestellt wird, ist völlig egal. Die Lebenszeit beeinträchtigt das in keinster Weise.

Gast
2007-03-09, 17:56:29
vielleicht meint er ja so was hier:

int func()
{
//...
}

int val = func();

und fragt sich wie lange der Rückgabewert der Funktion func() abgerufen werden kann. Die Antwort lautet: nur ganz kurz, nämlich beim Verlassen der Funktion. Kopiert ihn nicht genau dann in eine Variable (hier: val), ist er futsch.

ooAlbert
2007-03-09, 19:19:10
hm, ich meint schon das was vor mir geschrieben wurde :) sozusagen wie lange man den wert abgreifen kann. das bedeutet also:

int funktion

methode a

methode b

methode c

wenn das programm so aufgebaut wäre würde nur methode a den funktionswert aus dem return lesen können methode b und c würden ins leere greifen, bzw. einen fehler verursachen?

PatkIllA
2007-03-09, 19:34:43
aus der Notation ergibt sich überhaupt kein Zusammenhang.
Dein Ergebnis lebt mindestens so lange wie es irgendwo referenziert wird. Wird es das nicht mehr, löscht es irgenwann die Garbage Collection.
Bei primitiven Datentypen ist es noch etwas anders, da es da keine Referenzen gibt, sondern immer by Value kopiert wird.

ooAlbert
2007-03-09, 20:49:42
nagut dann halt anders, bzw. "genauer" ... die funktion gibt einen integer weiter, also ein primitiv... jetzt kommt die erste methode die direkt danach aufgerufen wird und holt sich den integer und schreibt den in eine neue lokale variable. wenn die jetzt abgearbeitet ist kann dann die darauffolgende methode immernoch den integer aus der ursprünglichen funktion abrufen oder hat den der gc dann schon weggeräumt?

Monger
2007-03-09, 20:50:54
nagut dann halt anders, bzw. "genauer" ... die funktion gibt einen integer weiter, also ein primitiv... jetzt kommt die erste methode die direkt danach aufgerufen wird und holt sich den integer und schreibt den in eine neue lokale variable. wenn die jetzt abgearbeitet ist kann dann die darauffolgende methode immernoch den integer aus der ursprünglichen funktion abrufen oder hat den der gc dann schon weggeräumt?
Ich glaub, ich versteh deine Verwirrung.
"=" ist nicht etwa eine Zuweisung, sondern kopiert die rechte Seite nach links. Bei Basisdatentypen wird der Wert kopiert, bei Objekten die Referenz. Solange du eine Variable benutzen kannst, ist sie auch gültig.

Machen wir mal ein paar Beispiele:

public int getNumber(); // dies ist die Signatur einer Methode, die einen int Wert zurückgibt.

publich void test(){ // Testmethode

int zahl = getNumber(); // die Methode rechts wird ausgeführt und durch ihr Ergebnis ersetzt.
// anschließend wird das Ergebnis nach links auf zahl kopiert.

getNumber(); // auch hier kommt eine Zahl raus. Da wir aber die Zahl nicht auf irgendeine benannte Variable umkopieren,
// verschwindet sie sofort im Nirvana
{ // hier richten wir mal einen neuen Scope ein
int zahl2 = getNumber(); // zahl2 ist nur innerhalb der Klammern sichtbar
}

zahl = zahl * 2; // deshalb funktioniert diese Zeile wunderbar...
zahl = zahl * 3; // ... und zwar so oft du willst ...
zahl2 = zahl2 * 2; // diese dagegen wird einen Compilerfehler werfen, weil die Variable außerhalb ihres Scopes verwendet wird.
}


Also: jede Variable kann innerhalb ihres Sichtbarkeitsbereichs (von ihrer Deklaration hin bis zur schließenden geschweiften Klammer) problemlos verwendet werden. Vorausgesetzt, man findet sie wieder. Was meistens (aber nicht immer) heißt, dass man ihr einen Namen gegeben haben muss.

ooAlbert
2007-03-09, 21:40:31
aha, das ist einleuchtend :) ich hatte vorher den irrglauben die funktion läuft durch und dann hängt der wert irgendwo... aber die funktion läuft ja erst durch wenn diese zuweisung für eine neue variable stattfindet ...

Monger
2007-03-09, 22:02:59
Ich denke, der wichtigste Satz für dich ist: jede Operation wird mit der rechten Seite (wenn es denn eine gibt) zuerst, von innen nach außen bearbeitet, und jede Methode wird durch ihr Ergebnis ersetzt.

Deshalb funktioniert z.B. auch sowas hier:

public class TestKlasse{
public Testklasse doSth();

}

// ab hier: Testmethode

Testklasse test = new Testklasse();
test.doSth(); // das kennst du sicher schon.

new Testklasse().doSth(); // Das hier tut genau das selbe wie oben
new Testklasse().doSth().doSth().doSth(); // und jetzt wirds abstrakt...

"new Testklasse()" ist im Prinzip auch nur eine Methode, nämlich der Konstruktor. Und der Rückgabewert des Konstruktors ist eine Instanz dieser Klasse - in diesem Fall also ein "Testmethode" Objekt.
Und auf einem Testmethode Objekt kann ich eine Methode "doSth()" ausführen. Und da "doSth()" als Rückgabewert wieder ein Objekt dieser Klasse hat, kann ich auch darauf wieder so eine Methode ausführen...

Du siehst, man kann den Gedanken beliebig komplex weiterspinnen.

Man darf bei Java nicht so furchtbar kompliziert denken. Java kennt eben KEINE Pointer Arithmetik. Stell dir jede Zeile als mathematischen Ausdruck mit Zahlen vor, die nach und nach durchgerechnet werden, dann tust du dir vermutlich leichter.

Gast
2007-03-13, 13:12:22
hm, ich meint schon das was vor mir geschrieben wurde :) sozusagen wie lange man den wert abgreifen kann. das bedeutet also:

int funktion

methode a

methode b

methode c
ich nehme mal an, das soll:

funktion();
methode_a();
methode_b();
methode_c();

heißen?

wenn das programm so aufgebaut wäre würde nur methode a den funktionswert aus dem return lesen können methode b und c würden ins leere greifen, bzw. einen fehler verursachen?bei dieser Programmstruktur würde gar keine der drei Methoden den Wert lesen können. Beim Verlassen von funktion() geht deren Rückgabewert verloren, da er nicht in eine Variable gespeichert wird. Die drei Methoden würden aber auch nicht "ins Leere greifen". Es gibt kein "Greifen", das sie machen könnten.
Der Zugriff auf den Rückgabewert von funktion() ist nur über die Variable möglich, in die der Rückgabewert kopiert wurde. Die Methoden müssen dann entweder einen Parameter haben, als der der Variablenwert übergeben wird:

int x = funktion();
methode_a(x);
methode_b(x);
methode_c(x);

und die Methoden müßten dann durch Auswerten ihres Parameters auf den Wert zugreifen, oder aber der Rückgabewert von funktion muß in einen Datenmember der Klasse gespeichert werden, von der die drei Methoden Funktionsmember sind:

this.x = funktion();
this.methode_a();
this.methode_b();
this.methode_c();

die drei Methoden lesen dann intern den Member x aus.

Gast
2007-03-13, 13:54:18
aha, das ist einleuchtend :) ich hatte vorher den irrglauben die funktion läuft durch und dann hängt der wert irgendwo... versuch doch mal den Code hinzuschreiben wie er dir vorgeschwebt hat.
Soweit ich dich verstehe, hast du geglaubt es gebe eine Art Funktion getLastReturnValue(), mit dem man den Rückgabewert der zuletzt aufgerufenen Funktion abrufen könne, etwa so:

funktion();
methode_a();

//...

// Definition von methode_a()
void methode_a()
{
getLastReturnValue(); // Rückgabewert der letzten vorherigen Funktion holen
//...
}

aber die funktion läuft ja erst durch wenn diese zuweisung für eine neue variable stattfindet ...hä? Nö. Die Funktion läuft dann durch, wenn sie aufgerufen wird. Dabei ist es egal, ob ihr Rückgabewert zugewiesen wird oder nicht:

int x = funktion(); // Funktion läuft durch, Rückgabewert wird in x gespeichert
funktion(); // Funktion läuft durch, Rückgabewert geht verloren

Gast
2007-03-13, 13:58:23
Man darf bei Java nicht so furchtbar kompliziert denken. Java kennt eben KEINE Pointer Arithmetik. das würde mich jetzt aber mal interessieren, was Albert's Problem mit Pointer-Arithmetik zu tun haben soll??