ich muss gerade für meine Übungsaufgabe die Klasse StringReader verwenden und bei der Benutzung dieser stellen sich mir ein paar Fragen, wie folgt :
1.) Wenn ich in einer Funktion als Argument eine Instanz der Klasse StringReader übergeben bekomme ( im Folgenden : "reader" ), kann ich dann eine neue Instanz von StringReader als Kopie von reader anlegen? Die Kostruktoren sehen so aus, als wäre das ohne Weiteres nicht möglich. Wenn ich zB StringReader newReader = reader; schreibe, würde ich ja nur eine Referenz auf das übergebene Objekt bekommen, sehe ich das richtig ? Schließlich gibt es zB keinen Konstruktor StringReader ( StringReader other ) ( copy ctor ). Wenn ich also mit einer Kopie des übergebenen Argumentes arbeiten will, bleibt mir nichts anderes übrig, als den String aus reader mit vielen read() aufrufen auszulesen ( da toString() nur Unsinn ausgibt ) und dann mit diesem entstanden String ein neuen StringReader zu erzeugen ( da ja StringReader ( String text ) existiert ) ?
2.) Das bringt mich zur nächsten Frage : Entfernt die read() Methode das gelesene Zeichen aus dem internen Buffer von StringReader? Die Dokumentation über StringReader sagt dazu leider nichts.
Eine dritte, allgemeine Frage stellt sich mir hier direkt nach dem Durchlesen von meinem eigenen Posting :
Wer legt fest, ob foo ( someObj ); eine Kopie von someObj oder eine Referenz davon übergibt?
In C++ ist das anhand der Signatur fest geregelt, in Java hat mir allerdings noch nie jemand eine Regel dafür genannt ( was nicht heißen soll, dass es keine gibt ). Sprich : Woher weiß ich ob ich in meinen Funktionen mit einer Kopie oder einer Referenz arbeite?
Eine dritte, allgemeine Frage stellt sich mir hier direkt nach dem Durchlesen von meinem eigenen Posting :
Wer legt fest, ob foo ( someObj ); eine Kopie von someObj oder eine Referenz davon übergibt?
In C++ ist das anhand der Signatur fest geregelt, in Java hat mir allerdings noch nie jemand eine Regel dafür genannt ( was nicht heißen soll, dass es keine gibt ). Sprich : Woher weiß ich ob ich in meinen Funktionen mit einer Kopie oder einer Referenz arbeite?
Damit verwirrst Du den C++-Kenner.
In Java gibt es ausschlißlich "call by value".
Deswegen funktionieren Zuweisungen an Parameter nicht als "Rückgabewert". Wenn also eine Referenz als Parameter übergeben wird, entsteht daraus in der aufgerufenen Methode eine neue Referenz mit dem selben Wert, wie in der aufrufenden Methode. Wenn man die Referenz in der aufgerufenen Methode auf ein neues Objekt zeigen lässt bekommt die aufrufende Methode (genauer die Referenz dort) das nicht mit.
1.) Wenn ich in einer Funktion als Argument eine Instanz der Klasse StringReader übergeben bekomme ( im Folgenden : "reader" ), kann ich dann eine neue Instanz von StringReader als Kopie von reader anlegen?
Wenn ich also mit einer Kopie des übergebenen Argumentes arbeiten will, bleibt mir nichts anderes übrig, als den String aus reader mit vielen read() aufrufen auszulesen
Zuerst mal ist StringReader ja ein Reader und als solcher kennt er die Anzahl der folgenden Zeichen eigentlich nicht.
Code:
toString()
soll aber bei jedem Aufruf den gleichen, für das Objekt charakteristischen Text ausgeben (vereinfacht: ein Text basierter Hashcode). Das geht bei Reader prinzipbedingt nicht.
Also Ich habe bei Deiner Anforderung 2 Fragen:
1. (wie schon gesagt) wozu brauchst Du eine Kopie? Anders als in C++ brauchst Du Dir ja keine Sorgen darüber machen, ob jemand anders zwichenzeitlich das Parameter-Objekt frei gibt...
2. Wieso ist der Parameter von Typ StringReader? Die basisclasse Reasder wäre doch viel sinnvoller weil flexibler...
2.) Das bringt mich zur nächsten Frage : Entfernt die read() Methode das gelesene Zeichen aus dem internen Buffer von StringReader? Die Dokumentation über StringReader sagt dazu leider nichts.
Damit verwirrst Du den C++-Kenner.
In Java gibt es ausschlißlich "call by value".
Deswegen funktionieren Zuweisungen an Parameter nicht als "Rückgabewert". Wenn also eine Referenz als Parameter übergeben wird, entsteht daraus in der aufgerufenen Methode eine neue Referenz mit dem selben Wert, wie in der aufrufenden Methode. Wenn man die Referenz in der aufgerufenen Methode auf ein neues Objekt zeigen lässt bekommt die aufrufende Methode (genauer die Referenz dort) das nicht mit.
Welchen Teil diese Verhaltens meinst Du?
Du kannst eine Referenz (was dem C-Pointer recht nahe kommt) an eine Methode weitergeben. Nicht mehr aber auch nicht weniger.
Huh, das verstehe ich jetzt nicht. Das klingt effizienter, aber ... . Wenn ich zB in C++ 2 Referenzen auf ein Objekt habe, dann ändert sich das referenzierte Objekt beim Verändern sowohl der einen als auch der anderen Referenz.
Gleiches müsste dann doch auch in Java geschehen, wenn ich eine Referenz kopiere erhalte ich ja eine, die trotzdem auf mein Ursprungsobjekt zeigt?
Code:
int A = 5; // A == 5
int& rA = A;
rA = 100; // A == 100
int& rB = A;
rB = 200; // A == 200
Genau dieses Verhalten meinte ich auch. Nur eben, dass die Zuweisungen innerhalb eines anderen Scopes ( Funktion in dem Fall ) geschehen.
Huh, das verstehe ich jetzt nicht. Das klingt effizienter, aber ... . Wenn ich zB in C++ 2 Referenzen auf ein Objekt habe, dann ändert sich das referenzierte Objekt beim Verändern sowohl der einen als auch der anderen Referenz.
Gleiches müsste dann doch auch in Java geschehen, wenn ich eine Referenz kopiere erhalte ich ja eine, die trotzdem auf mein Ursprungsobjekt zeigt?
Vergiss, was Du aus C++ über Referenzen weist. In Java ist eine Referenz einfach eine Variable, mit der man ein Objekt (von einem bestimmten Typ) "festhält".
Den
Code:
&
-Operator um auf Adressen zuzugreifen gibt es in Java nicht. Überhaupt kannst Du in Java niemals auf die Speicheradresse eines Objekts zugreifen. Das geht schon deshalb nicht, weil der GarbageCollector Objekte nach eigenem Gutdünken wild im Speicher hin- und her- verschieben kann, wir er es gerade braucht. Java sorgt intern dafür, dass deine Referenzen danach immer noch auf die selben Objekte (an ihren neuen Speicheradressen) zeigen.