Strings, wie etwa
LearningGoal@4517d9a3
sind lediglich die java.lang.Object::toString() Repräsentation einer Instanz eines Referenztyps (also von java.lang.Object abgeleitete Klasse), wenn die toString() Methode für diese Klasse nicht überschrieben wurde.
Und die java.lang.Object::toString() Implementierung gibt einen String zurück, der sich aus dem einfachen Klassennamen (Klasse ohne Package - für Arrays gibt's eine Sonderbehandlung), einem @-Zeichen gefolgt von dem HashCode (wie von der hashCode() Methode für dieses Objekt zurückgeliefert) in hexadezimaler Schreibweise zusammensetzt.
Die hashCode() Methode selbst wird auch von java.lang.Object::hashCode() an jede Klasse vererbt (und kann auch überschrieben werden). Die java.lang.Object Implementierung gibt hier einfach den System.identityHashCode() des Objektes zurück.
Dieser ist in HotSpot als eine Pseudozufallszahl implementiert (aber z.B. in Azul's Zing JVM als die untersten 32-bit der Speicheradresse der Instanz zum Zeitpunkt des ersten Aufrufes von System.identityHashCode() für dieses Objekt).
Letztlich ist aber im Standard nicht definiert, wie der identityHashCode() genau aussehen soll. Es ist lediglich definiert, dass der Identity Hashcode eines Objektes über die gesamte Lebenszeit desselben Objektes auch denselben Wert zurückliefern muss.
EDIT: Fun facts: Man kann mit den JVM Argumenten
-XX:+UnlockExperimentalVMOptions -XX:hashCode=4
auch in HotSpot steuern, dass die initiale Speicheradresse eines Objektes als Identity Hashcode verwendet werden soll. Siehe
https://stackoverflow.com/questions...ue-of-an-object-on-64-bit-jvm#answer-26049632 für alle möglichen Implementierungen in HotSpot.