Wie bekommt man die „Objektreferenz“ eines Objekts in Java, wenn toString () und hashCode () außer Kraft gesetzt wurden?

StackOverflow https://stackoverflow.com/questions/580984

  •  06-09-2019
  •  | 
  •  

Frage

Ich möchte für Debugging-Zwecke die „Objektreferenz“ eines Objekts in Java drucken. D. h um sicherzustellen, dass das Objekt die gleiche (oder andere) ist abhängig von der Situation.

Das Problem ist, dass die betreffende Klasse von einer anderen Klasse erbt, die sowohl toString außer Kraft gesetzt hat () und hashCode (), die in der Regel mir die ID geben würden.

Beispiel Situation: Ausführen einer Multi-Threaded-Anwendung, wo ich (während der Entwicklung) alle überprüfen möchten, ob die Fäden die gleiche Instanz einer Ressource-Objekt verwenden oder nicht.

War es hilfreich?

Lösung

Was genau planen Sie mit ihm auf zu tun (was Sie tun möchten, macht einen Unterschied, mit dem, was Sie anrufen müssen).

hashCode , wie in dem JavaDocs definiert, sagt:

  

So viel wie vernünftigerweise praktikabel ist, die Methode hashCode nach Klasse Object definierte zurückgibt verschiedene ganze Zahlen für verschiedene Objekte. (Dies wird typischerweise implementiert durch die interne Adresse des Objekts in eine ganze Zahl konvertieren, aber diese Implementierung Technik ist nicht von der Programmiersprache Java ™ erforderlich.)

Wenn Sie also hashCode() verwenden, um herauszufinden, ob es sich um ein einzigartiges Objekt im Speicher ist das kein guter Weg ist, es zu tun.

System.identityHashCode führt folgendes aus:

  

Gibt den gleichen Hash-Code für das Objekt, wie durch die Standardmethode hashCode () zurückgegeben werden würde, ob oder ob nicht die Klasse des gegebenen Objekt überschreibt hashCode (). Der Hash-Code für die Null-Referenz Null ist.

Welche, für das, was man tut, klingt wie, was Sie wollen ... aber was wollen Sie sicher sein könnte, nicht zu tun, je nachdem, wie die Bibliothek implementiert wird.

Andere Tipps

Dies ist, wie ich es gelöst:

Integer.toHexString(System.identityHashCode(object));

Double gleich == prüft immer auf Objektidentität, und zwar unabhängig von der Durchführung Objekte von hashCode oder gleich. Natürlich - stellen Sie sicher, dass die Objektreferenzen Sie vergleichen sind volatile (in einer 1.5+ JVM).

Wenn Sie wirklich das ursprüngliche Objekt toString Ergebnis haben müssen (auch wenn es nicht die beste Lösung ist für Ihr Beispiel Use-Case), hat die Commons Lang-Bibliothek ein Verfahren ObjectUtils.identityToString (Object) , die das tun, was Sie wollen. Von der JavaDoc:

public static java.lang.String identityToString(java.lang.Object object)
  

Ruft das toString das wäre   wenn eine Klasse von Objekt erzeugt nicht tat   außer Kraft setzen toString selbst. null Wille   null zurück.

 ObjectUtils.identityToString(null)         = null
 ObjectUtils.identityToString("")           = "java.lang.String@1e23"
 ObjectUtils.identityToString(Boolean.TRUE) = "java.lang.Boolean@7fa"

Sie können nicht sicher tun, was Sie da die Standard hashCode wollen () kann die Adresse nicht zurück, und erwähnt, mehrere Objekte mit demselben hashCode sind möglich. Der einzige Weg zu erreichen, was Sie wollen, ist die hashCode () Methode für die betreffenden Objekte tatsächlich außer Kraft setzen und garantieren, dass sie alle eindeutigen Werte liefern. Ob dies möglich in Ihrer Situation ist eine andere Frage.

Für das Protokoll habe ich mehrere Objekte mit dem gleichen Standard hashcode in einem IBM VM erlebte in einem laufenden WAS-Server. Wir hatten einen Defekt, wo Objekte in eine Remote-Cache gestellt werden würde, weil dieser überschreibt. Das war ein Augenöffner für mich an diesem Punkt, da ich der Standard-Hash-Code war die Objekte Speicheradresse als auch angenommen.

Fügen Sie eine eindeutige ID auf alle Ihre Instanzen, d.

public interface Idable {
  int id();
}

public class IdGenerator {
  private static int id = 0;
  public static synchronized int generate() { return id++; }
}

public abstract class AbstractSomething implements Idable {
  private int id;
  public AbstractSomething () {
    this.id = IdGenerator.generate();
  }
  public int id() { return id; }
}

von AbstractSomething erweitern und diese Eigenschaft abfragen. Wird in einem einzigen vm sicher sein (kein Spiel unter der Annahme, mit Classloader spielt um Statik zu bekommen).

können wir einfach den Code aus tostring der Objektklasse kopieren die bekommen Referenz der Zeichenfolge

class Test
{
  public static void main(String args[])
  {
    String a="nikhil";     // it stores in String constant pool
    String s=new String("nikhil");    //with new stores in heap
    System.out.println(Integer.toHexString(System.identityHashCode(a)));
    System.out.println(Integer.toHexString(System.identityHashCode(s)));
  }
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top