Bleibt toString() konstant?

A

anonym

Gast
Hallo,

also: Wenn ich ein Objekt (beliebiger Typ) erzeuge und dann darauf toString() aufrufe (genaugenommen nutze ich ObjectUtil.identityToString(), weil's in einer Bibliothek ist und ich abfangen möchte, dass toString() überschrieben sein könnte, ich kann da wirklich alles kriegen!), bekomme ich einen String von der Art "pack.age.Class@12345abc". Das ist soweit toll.

Aber: Was passiert, wenn ich so ein Objekt erzeuge, toString() aufrufe, dass Ding benutzte (Eigenschaften ändere, Methoden darauf aufrufe, es als Parameter an Methoden übergebe, es vielleicht mal kurz mit JNI an C abgebe...hier kann wieder alles passieren, was der Benutzer meiner Bibliothek möchte), wird toString (bzw. ObjectUtil.identityToString()) dann zu einem späteren Zeitpunkt noch denselben String (bzw. einen String, der zu dem aus dem ersten Aufruf equals() ist) zurückgeben?

Insgesamt ist mir egal, was ich bekomme. Ich muss nur an der zweiten Stelle eindeutig feststellen können, ob es dasselbe Objekt ist, wie an der ersten Stelle. Bestenfalls ohne das Objekt selbst zu referenzieren, da ich den GC nicht stören möchte (kann auch sein, dass das Objekt an der zweiten Stelle nie ankommt).

Mein Plan B wäre ein Interface, dass eine getIdentifier()- Methode hat, die einen eindeutigen Wert für jedes Objekt zurükgeben muss. Daran stört mich allerdings, dass ich dann nicht mehr beliebige Objekte akzeptieren kann. Habt ihr sonst Vorschläge?

Schöne Grüße,
campino
 

HoaX

Top Contributor
Nein, toString() gibt dir nicht unter Garantie immer das Selbe zurück. Das wäre nur der Fall wenn es eine Klasse fix so implementiert hat.
ObjectUtil ist keine Standardklasse, keine Ahnung wo du die her hast und entsprechend auch nicht was darin steckt. Aber mir ist auch kein Weg bekannt wie man einen eindeutigen, unveränderlichen String zu einem Objekt erzeugen kann, also wird es auch diese Klasse nicht können.
Das nach dem @ ist idR der Hashcode, und bei diesem ist die Wahrscheinlichkeit doch sehr hoch, dass er sich durch Ändern von Attributen ändert.

Edith sagt: Einen Weg kenne ich doch, aber die Klasse wird wohl kaum eine Referenz auf jedes übergebene Objekt speichern ...
 
S

SlaterB

Gast
"pack.age.Class@12345abc" ist doch das toString() von Object, mit bekanntermaßen Hashcode vom Speicherplatz des Objektes,
wieso sollte sich dieser Hashcode 'mit hoher Wahrscheinlichkeit' ändern?

dass die Methode überschrieben werden kann wird ja bereits mit der externen Library abgefanden, es ist diese Klasse hier:
ObjectUtils (Commons Lang 2.5 API)

-----

ob sich der Hashcode von Object ändern kann, weiß ich nicht genau, habe ich aber noch nie gesehen,
ich denke eher nicht

problematisch wird es, wenn Objekte kopiert werden, etwa per RMI oder Serialisierung in anderen Programmen auftauchen oder im selben Programm ein zweites Mal, diese neuen Objekte haben dann für gewöhnlich einen komplett anderen Hashcode, sind eben separte Objekte,
'mit JNI an C' fällt vielleicht darunter
 

HoaX

Top Contributor
Ok, wenn es wirklich immer der in Object implementierte HashCode ist, dann gebe ich dir recht. Der HashCode einer abgeleiteten Klasse wird sich aber sicherlich ändern können.
 

André Uhres

Top Contributor
[c]hashCode[/c] macht Folgendes (nach Javadoc):

As much as is reasonably practical, the hashCode method defined by class Object does return distinct integers for distinct objects. (This is typically implemented by converting the internal address of the object into an integer, but this implementation technique is not required by the JavaTM programming language.)

Eine theoretische Garantie, dass gleiche hashCodes auch gleiche Objekte bedeuten, gibt es demnach nicht. Aber die Wahrscheinlichkeit, dass es sich in der Praxis so verhält, ist wohl sehr hoch.

Gruß,
André
 
A

anonym

Gast
Hallo,

erstmal vielen Dank euch allen.
@HoaX: Entschuldige bitte, irgendwie hatte ich im Kopf, ich hätte dazu geschrieben, wo ich die ObjectUtils her habe. Offenbar hatte ich da mehr im Kopf als im Beitrag...aber zum Glück hat SlaterB ja nachgeliefert.

Ich habe mal ein bisschen weitergegoogelt. Die Implementierung von ObjectUtil nutzt java.lang.System.identityHashCode(). Diese Funktion macht tatsächlich was mit der Speicheradresse. Anschließend wird dieser HashCode in den Object- Header im Speicher geschrieben, bleibt also unverändert. Zu bemerken ist dabei, dass das in der Sun JVM zwar so ist und dass es die HashMap- Implementierung zerstören würde, wenn nicht, dass das aber niemand garantiert.
 

Murray

Top Contributor
Mit Klassen, die hashCode() so überschreiben, dass auch nicht-identische Objekte den gleichen Wert liefern, könnte man umgehen, indem man auf System (Java Platform SE 6) ausweicht:


Java:
public static String getIDStr( final Object o) {
     return o == null ? "" : ( o.getClass().getName() + '@' + Integer.toHexString( System.identityHashCode( o)));
}

(Wobei auch das natürlich von der Annahme lebt, dass a) Object.hashCode() so implementiert ist, dass die Speicheradresse des Objekts verwendet wird und b) sich diese Adresse niemals ändert. Beides dürfte in gängigen VMs der Fall sein; durch die Spec garantiert ist das aber wohl nicht)

/EDIT: offenbar mal wieder etwas zu langsam
 

fastjack

Top Contributor
ObjectUtil.identityToString() kommt aus Apache-Commons-Lang und dient dazu das Ergebnis der nicht überschriebenen toString()-Methode abzufragen, wie Murray schon zeigte.

... wird toString (bzw. ObjectUtil.identityToString()) dann zu einem späteren Zeitpunkt noch denselben String (bzw. einen String, der zu dem aus dem ersten Aufruf equals() ist) zurückgeben?

nur wenn Du nicht an einer anderen Stelle ein neues erzeugst und zurückgibst. Ansonsten wird es nicht funktionieren. Das ist aber sehr gewagt. Angenommen Du übergibt das Objekt an JNI, dort wirdes verarbeitet, zwischendurch in der VM geändert (auf null gesetzt oder so), der GC räumt schön ab, dann kann ein neues anderes Objekt diese Speicherstelle einnehmen und die Identität des alten annehmen.
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
JavaNewbie2.0 Programm bleibt "stehen" Allgemeine Java-Themen 2
Salo JDK installieren java home bleibt nicht Allgemeine Java-Themen 9
H Thread bleibt stehen bei jar in jar Allgemeine Java-Themen 1
T SE Development Kit 8 73 installer bleibt stehen Allgemeine Java-Themen 5
T Programm bleibt ohne Fehler stehen Allgemeine Java-Themen 4
R JasperReport bleibt leer Allgemeine Java-Themen 3
K Schreiben von Bildern: Bild bleibt leer Allgemeine Java-Themen 7
D seit sytemabsturz bleibt eclipse hängen beim starten Allgemeine Java-Themen 3
T JOptionPane.showMessageDialog() bleibt hängen Allgemeine Java-Themen 5
B Spiel bleibt hängen Allgemeine Java-Themen 3
E JButton bleibt in der JTable Allgemeine Java-Themen 2
MQue JFrame bleibt hängen Allgemeine Java-Themen 3
G Es bleibt stehen ! Allgemeine Java-Themen 8
R Wert in Hashtable ändern (Key ändern, Value bleibt) Allgemeine Java-Themen 3
B Frame schließt sich aber VM bleibt am Leben Allgemeine Java-Themen 3
thor_norsk toString() - Methode Allgemeine Java-Themen 6
Encera Unterschied zweier "toString"-Methoden Allgemeine Java-Themen 1
A Ist ein enum hier richtig? Enum toString() Methode. Allgemeine Java-Themen 1
T Sinn einer toString Methode Allgemeine Java-Themen 3
L ToString-Methode Allgemeine Java-Themen 6
Neoline Interpreter-Fehler Probleme mit Arrays.toString Allgemeine Java-Themen 7
M BufferedImage toString() überschreiben Allgemeine Java-Themen 5
E Seltsamer aufruf von java.util.Date.toString() Allgemeine Java-Themen 3
P Element toString Allgemeine Java-Themen 9
fastjack jUnit und Test von equals, hashCode, toString Allgemeine Java-Themen 11
sylo toString() Methode eines Interfaces überladen. Allgemeine Java-Themen 17
G Arrays.toString Allgemeine Java-Themen 4
G toString() von java.io.File überschreiben Allgemeine Java-Themen 8
V Einfache toString() generieren? Allgemeine Java-Themen 6
S toString() für alle Member einer Klasse. Allgemeine Java-Themen 6
R toString() methode überschreiben mit rekursivem aufruf. Allgemeine Java-Themen 8
G toString(), Funktionsweise? Allgemeine Java-Themen 7
I Problem mit toString-Methode Allgemeine Java-Themen 6
M .toString() mit RegEx auseinanderpflücken. Allgemeine Java-Themen 17
B (String) und toString(), woliegt der Unterschied? Allgemeine Java-Themen 4
F Einzelne Einträge im Array als konstant festlegen Allgemeine Java-Themen 2
A Referenzen / HashCodes nicht konstant? Allgemeine Java-Themen 2

Ähnliche Java Themen

Neue Themen


Oben