-
23. 01. 2012, 19:25 #1
[Java] echten Pointer ersetzen
Hey,
Ich komme ja eigentlich aus der C++ ecke, bin aber auf Grund der Umstände gezwungen Java zu benutzen, und stolper immer wieder über die Sprache, jetzt bin ich an einem Punkt angekommen, wo ich gerade mal nicht weiterkomme, ohne mir mein Design zu versauen.
In Java gibt es ja keine echten Pointer, was ich damit meine, ist, dass es keine Möglichkeit gibt, ein Parameter, das man einer Methode übergibt nach außen hin zu verändern, wie es in C++ mit Pointern oder Referenzen geht.
Ich muss aber genau das tun.
Ich empfange Daten über einen Socket, und möchte die parsen, und in ein Objekt einarbeiten, was für ein Objekt ist aber nicht klar, lediglich, dass es ein bestimmtes Interface implementiert, deswegen kann ich das auch nicht über den Rückgabe wert machen, meines Wissens nach.
in C++ würde ich das etwa so machen:
und dann das Packet in der Methode befüllen.Code:void readMyPacket(MyPacket* packet);
In Java hatte ich mir ungefähr sowas vorgestellt:
Aber das geht natürlich nicht, ich liste mal die Fehlermeldungen auf:Code:public synchronized T readMyPacket<T implements MyPacket>() throws IOException{ T packet= new T(); ...... }
- Description Resource Path Location Type Illegal modifier for the field readMyPacket; only public, protected, private, static, final, transient & volatile are permitted
- Description Resource Path Location Type Syntax error on token ">", Identifier expected after this token
- Description Resource Path Location Type Syntax error, insert ";" to complete FieldDeclaration
- Description Resource Path Location Type T cannot be resolved to a type
Die Fehler sind ja auch logisch irgendwo, allerdings diente die Zeile auch mehr dazu, euch meine Idee zu vermitteln.
Ich hoffe ihr versteht was ich meine, und könnt mir vllt eine saubere Lösung bieten.
gruß Uzaku
-
23. 01. 2012, 19:53 #2
Re: [Java] echten Pointer ersetzen
Igitt! Methoden die Pointer umbiegen.

Sorry aber sowas ist einfach hässlich und führt nicht gerade zu wartbarem Code. Hat schon seinen Sinn, dass moderne Programmiersprachen auf Pointer verzichten.
(Java ist da ja in guter Gesellschaft).
Also ich geh mal davon aus, dass du die Daten, die du über das Socket empfängst direkt in der "readMyPacket" liest und parst, dann entscheidest, was für ein Objekt du zu erzeugst, dieses Objekt dann in irgendeiner Form bearbeitest und später halt nochmal brauchst.
Das sieht in Java folgendermaßen aus:
Code:public synchronized MyPacket readMyPacket() throws IOException{ //Read data from Socket // Decide what to do MyConcretPacket result = new MyConcretPacket(); //MyConcretePacke muss natürlich MyPacket implementieren //Change result result.doAmazingStuff() return result; }Geändert von -Icarus- (23. 01. 2012 um 20:06 Uhr)
-
23. 01. 2012, 20:01 #3
Re: [Java] echten Pointer ersetzen
Das würde ich aber in C++ genauso machen. Der Rückgabetyp wäre dann eben ein Pointer auf die Basisklasse/Interface. Einen Pointer als Parameter zu übergeben klappt auch nur dann sinnvoll wenn das Objekt vorher erzeugt wird. Aber das ist ja nicht der Fall so wie ich das Problem verstehe.
-
23. 01. 2012, 20:05 #4
Re: [Java] echten Pointer ersetzen
Ich glaube ihr habt mir falsch verstanden, aber danke schon mal für die Antworten.
Ich habe verschiedene Objekte (verschieden Typs), die von MyPacket erben, und die außerhalb davon erstellt werden.
Und die möchte ich dann in readMyPacket befüllen (zumindest die Parts die aus MyPacket sind)
EDIT: Die Java Version is nur die Notlösung, weil mir nichts besseres eingefallen ist.
Was auch noch ginge, wäre in der read-Methode.
Abhängig vom Empfangenen Wert, das Objekt zu erstellen, wie schon erwähnt wurde.
Allerdings müsste ich dann außerhalb der Methode caste, und das möchte ich nicht, weil ich dann auch in der Basis klasse irgendwie vermerken müsste, zu was ich das casten soll.
Gibt es einen Variablen Rückgabetyp?Geändert von Uzaku (23. 01. 2012 um 20:11 Uhr)
-
23. 01. 2012, 20:13 #5
Re: [Java] echten Pointer ersetzen
Hä? Also nochmal langsam. Du hast mehrere Instanzen von MyPacket. (Also eine collection, ein Array oder was weiß ich).
Diese Instanzen willst du einfach nur verändern und mit ihnen weiterarbeiten?
Aber warum versuchst du dann in deinem Java Beispiel Instanzen erzeugen?
Code:public synchronized MyPacket[] readMyPacket(MyPacket[] pakets) throws IOException{ // Objekte verändern, Array wieder zurückgeben. return pakets; //Das zurückgeben ist eigentlich optional }
-
23. 01. 2012, 20:18 #6
Re: [Java] echten Pointer ersetzen
Wie gesagt als Notlösung.
Ich habe quasi 5 Lists, mit 5 unterschiedlichen Objekt-Typen, die aber alle von Mypacket erben.
Die würde ich einfach nur befüllen wollen in readMyPacket(), und danach mit ihnen weiterarbeiten. Vorher wären sie quasi nutzlos, können also auch in readMypacket erstellt werden. ABER dnach ist eben wichtig, was für ein Typ diese Objekte haben.
Und das kann ich ja nicht wirklich wissen außerhalb von readMyPacket() weil ich nicht 5 verschiedene Rückgabetypen haben kann.
EDIT:
Ok mir ist gerade aufgefallen, dass ich vorher ja auch noch nicht weiß, was rauskommt.
Ich muss es also so oder so in der Methode erstellt werden.
Und dann muss ich so oder so draußen umcasten auch wenn ich noch nicht genau weiß, wie ich außerhalb der Methode ermittel worauf ich umcasten muss.Geändert von Uzaku (23. 01. 2012 um 20:24 Uhr)
-
23. 01. 2012, 20:32 #7
Re: [Java] echten Pointer ersetzen
Wenn du in deinem Code nach dem erstellen wissen musst, um was für konkrete Klassen es sich handelt ist das ein Zeichen für schlechten Code. Zumindest zeugt es davon, das dein Code nicht objektorientiert ist.
Das gilt übrigens für alle Programmiersprachen.
Polymorphismus heißt hier das Zauberwort.
Edit!:
http://www.javapractices.com/topic/TopicAction.do?Id=31
-
23. 01. 2012, 20:58 #8
Re: [Java] echten Pointer ersetzen
Das ist schon irgendwo wahr

Ich werde nochmal in mich gehen, und das ganze überdenken müssen.
-
23. 01. 2012, 21:29 #9
Re: [Java] echten Pointer ersetzen
In Java ist es aber prinzipiell möglich festzustellen von welchem Typ ein Objekt ist, von dem man nur ein Basisreferenz hat. Das Zauberwort heißt instanceof. Das heißt aber icht, dass das besser ist als deine Programmstruktur nochmal zu überdenken.
Die Kernfrage dabei ist eigentlich: Was hast du mit den Objekten vor? Ist es tatsächlich wichtig zu entscheiden von welchem Typ sie sind, oder kann man vielleicht einfach eine gemeinsame Methode definieren, die von jedem Typ unterschiedlich implementiert ist.
-
23. 01. 2012, 22:35 #10
Re: [Java] echten Pointer ersetzen
Java kann leider nur Call By Value.
Was du aber machen kannst ist ein Wrapper um die Daten schreiben, dann kannst du deine Daten in ein Property des Wrappers schreiben. Also sowas in der Art von
und nach der dem Aufruf der read Methode ist data im übergebenen Objekt gesetzt. Dazu muss halt schon ein initialisiertes Objekt übergeben werden. Falls die Objektinitialisierung dynamisch geschehen soll kannst du das Factory Pattern oder etwas gleichwertiges verwenden.Code:public void read(MyPacket packet) { PacketData data = //hier Datenleselogik einfügen ;) packet.setData(data); }
Edit: Wegen des Variablen Rückgabetyps schließ' ich micht Icarus an: Polymorphie <3!Geändert von zilluss (23. 01. 2012 um 22:41 Uhr)
-
23. 01. 2012, 22:48 #11
Re: [Java] echten Pointer ersetzen
???
Seit wann denn das? Mag ja sein dass das für die Basistypen int, float, ... gilt, aber alle Objekte in Java werden doch sowieso nur über Referenzen repräsentiert. Dann ist jeder Methodenaufruf der Objekte übergibt automatisch call by reference.
Oder bin ich da jetzt völlig daneben? Ich bin jetzt nicht der Javaexperte, aber das würde mich doch sehr wundern.
-
23. 01. 2012, 23:03 #12Mitglied
- Registriert seit
- May 2009
- Beiträge
- 1.888
Re: [Java] echten Pointer ersetzen
Da du die Referenz in einem solchen Fall nicht ändern kannst (nur das Objekt das per Referenz übergeben wurde kannst du im Rahmen der Möglichkeiten verändern) kommt dann wieder Call by Value raus, nur der Value ist halt eine Referenz.
Kann man sich drüber streiten wird aber in der Literatur so gehandhabt.
Mögliche Lösung daraus für den OP:
Übergib' eine Referenz auf ein Objekt und du darfst zwar nicht diese Referenz ändern aber den "Inhalt" des übergebenen Objekts.
Klappt z.B. toll mit Arrays oder Collections, du darfst zwar nicht die Referenz ändern aber den Inhalt von Array bzw. Collection...
Aaabär:
Das sein eigentlich böses Programmieren mit Seiteneffekten, so eine Methode sollte nix an dem Objekt fummeln (können).
Um dies zu erzwingen (in Java nötig, in anderen Sprachen auch anders möglich (const in C/C++ z.B.)) gibt es halt immutable Datentypen, die kann man gerne als Referenz übergeben aber kann eher nicht an deren Inhalt rumspielen.
Besser wäre deine Methode bekommt Daten übergeben und gibt einen Datentyp zurück der ein Interface implementiert.
Wenn du dann polymorph gesehen alles richtig gemacht hast kann dir der genaue Datentyp am Popo vorbeigehen solange nur das gewünschte Interface implementiert wird.
Und ja aus deinen Äußerungen folgt daher das dein Design eher nicht so gut ist und dein Problemlösungsansatz eher dein Design anpassen sollte als dir "Tricks" zu überlegen um die Sprachhürden zu umgehen...
-
23. 01. 2012, 23:04 #13
Re: [Java] echten Pointer ersetzen
Nein, die Referenz wird als value übergeben und damit ist das auch call by value.Dann ist jeder Methodenaufruf der Objekte übergibt automatisch call by reference.
-
23. 01. 2012, 23:45 #14
Re: [Java] echten Pointer ersetzen
Hm, so hab ich das noch nie gesehen. Aber wo ist da dann der Unterschied zu einem call by reference in C++ beispielsweise (Basisdatentypen jetzt mal ausgencodeommen). Da kann ich ja dann auch nur das übergebene Objekt ändern und nicht etwa ein neues Objekt zurückgeben. Natürlich kann ich in C++ eine Referenz auf einen Pointer übergeben und dann den Pointer ändern, aber das ist ja wieder was anderes.
Was das bringen soll ist aber sowieso fragwürdig, wenn man das Objekt einfach zurückgeben kann, ob jetzt als Pointer oder Referenz auf die Basisklasse.
-
24. 01. 2012, 00:31 #15Mitglied
- Registriert seit
- May 2009
- Beiträge
- 1.888
Re: [Java] echten Pointer ersetzen
C++ ist Default Call by value und hat eine eigene Syntax für die Abweichung Call by reference.
Java hat offiziell kein Call by reference aber übergibt alles was über primitive Datentypen hinausgeht als Referenz.
Daher die unterschiedliche Benamsung obwohl es bei nicht primitiven Datentypen auf das gleiche hinausläuft.
Man kann sich da gerne drüber streiten aber offiziell ist Java halt "Call by value only" auch wenn dies bei nicht primitiven Datentypen auf "Call-by-value where the value is a reference" hinausläuft.
Da dies bei primitiven Datentypen nicht funktioniert hat Java so offiziell kein Call by reference.
-
24. 01. 2012, 06:14 #16Mitglied
- Registriert seit
- Oct 2009
- Beiträge
- 703
Re: [Java] echten Pointer ersetzen
Polymorphie ist i.d.R. natürlich besser und auch aus einer objektorientierten Sicht "korrekter" aber ist leider keine Alheilmittel (aus wirtschaftlichen Gründen). Sollte man natürlich genügend Zeit zur Verfügung haben ist eine ordentliche Anpassung an den Klassen natürlich wesentlich sinnvoller.
Unter C# hat man bspw. die Möglichkeiten die implementierten Interface des Objektes bzw. von der Implementierunsklasse abzurufen. Das geht ganz bestimmt auch in Java.
Man sollte damit jedoch aufpassen, da man sich mit dieser Lösung eine zweite Kategorisierungsebene in die Anwendung einzieht (k.a wie ich es besser beschreiben soll).
Ist natürlich unschön
. Bei Reflektions wird es jedoch schon mal an der einen oder anderen Stelle eingesetzt.
-
24. 01. 2012, 08:25 #17
Re: [Java] echten Pointer ersetzen
Hab ich oben so beschrieben, dass sich der TS auch eine Art Wrapper um die Daten machen kann. Es ist tatsächlich so, dass man mit solchen Lösungen vorsichtig sein sollte. Aber wenn das Protokoll der Objektkommunikation (in diesem Fall: Objekt wird übergeben und innerhalb der Methode befüllt) eindeutig ist und auch nur an einer Stelle verwendet wird kann man es so machen. Für den Anwendungsfall, den der TS beschreibt sollte er, wie du sagst, wohl lieber einen polymorphen Rückgabewert verwenden.
-


Zitieren

mehr lesen...







Resident Evil 6 erscheint in...
Heute, 15:21 in gulli:news