Chciałbym wydrukować "odniesienie do obiektu" obiektu w Javie dla celów debugowania. To znaczy, aby upewnić się, że przedmiot jest taki sam (lub inny) w zależności od sytuacji.
Problem polega na tym, że omawiana klasa dziedziczy z innej klasy, która nadpisała zarówno toString (), jak i hashCode (), co zwykle daje mi identyfikator.
Przykładowa sytuacja: Uruchomienie aplikacji wielowątkowej, w której chcę (podczas programowania) sprawdzić, czy wszystkie wątki używają tego samego wystąpienia obiektu zasobu, czy nie.
Odpowiedzi:
Co dokładnie planujesz z tym zrobić (to, co chcesz zrobić, ma znaczenie dla tego, do czego będziesz musiał zadzwonić).
hashCode
, zgodnie z definicją w JavaDocs, mówi:Więc jeśli używasz,
hashCode()
aby dowiedzieć się, czy jest to unikalny obiekt w pamięci, nie jest to dobry sposób, aby to zrobić.System.identityHashCode
wykonuje następujące czynności:Co, z powodu tego, co robisz, brzmi jak to, czego chcesz ... ale to, co chcesz zrobić, może nie być bezpieczne, w zależności od sposobu implementacji biblioteki.
źródło
Oto jak to rozwiązałem:
źródło
Double equals
==
zawsze sprawdza na podstawie tożsamości obiektu, niezależnie od implementacji obiektu hashCode lub equals. Oczywiście - upewnij się, że porównujesz odniesienia do obiektówvolatile
(w JVM 1.5+).Jeśli naprawdę musisz mieć oryginalny wynik Object toString (chociaż nie jest to najlepsze rozwiązanie dla twojego przykładowego przypadku użycia), biblioteka Commons Lang ma metodę ObjectUtils.identityToString (Object) , która zrobi to, co chcesz. Z JavaDoc:
źródło
Nie możesz bezpiecznie robić tego, co chcesz, ponieważ domyślny hashCode () może nie zwrócić adresu, a jak już wspomniano, możliwych jest wiele obiektów z tym samym hashCode. Jedynym sposobem osiągnięcia tego, co chcesz, jest faktycznie przesłonięcie metody hashCode () dla danych obiektów i zagwarantowanie, że wszystkie one dostarczają unikalnych wartości. To inna kwestia, czy jest to wykonalne w Twojej sytuacji.
Dla przypomnienia, doświadczyłem wielu obiektów z tym samym domyślnym hashcode na maszynie wirtualnej IBM działającej na serwerze WAS. Mieliśmy błąd polegający na tym, że obiekty umieszczane w zdalnej pamięci podręcznej były przez to nadpisywane. To było dla mnie otwarciem oka w tamtym momencie, ponieważ założyłem, że domyślnym hashcode był również adres pamięci obiektów.
źródło
Dodaj unikalny identyfikator do wszystkich swoich instancji, tj
Rozszerz z AbstractSomething i wykonaj zapytanie o tę właściwość. Będzie bezpieczny w pojedynczej maszynie wirtualnej (zakładając, że nie ma gry z programami ładującymi klasy w celu obejścia statystyk).
źródło
sun.misc.Unsafe
możemy po prostu skopiować kod z tostring klasy obiektu, aby uzyskać odniesienie do łańcucha
źródło