2012-09-16 8 views
8

Wenn ein Class<T> als Teil eines Schlüssels einer Map verwendet werden muss, was ist der richtige Weg, um die hashCode und equals zu definieren?
A Class<T> erbt die, die von Object, die als Referenz Gleichheit überprüfen und gibt die Speicheradresse als Hash-Code, aber es ist nicht klar, was die sinnvolle Definition von equals und hashCode Definition eines Class<T> in meinem Kopf ist.
Sollte ich beispielsweise theClass.getClass().hashCode(); verwenden (wo wir Class<T> theClass; haben), um die Methoden der tatsächlichen Instanz zu verwenden?
Aber das scheint nicht die richtige Sache zu sein.
zum Beispiel in dem javadoc für Class<T>:Wie definiert man HashCode und equals für eine java.lang.Class <T>?

Jedes Array zu einer Klasse gehört auch, dass als Klasse Objekt reflektiert wird, die von allen Arrays mit dem gleichen Elementtyp und Anzahl von Dimensionen gemeinsam benutzt wird

So scheint es in einigen Fällen die gleiche Class<T> ist unter den Objekten geteilt? Also, was wäre der Weg zu folgen? Vielleicht verwenden Sie theClass.hashCode() und theClass.equals() Referenzgleichheit zu verwenden? Nicht sicher hier überhaupt.

+0

Es gibt nichts zu definieren, da Hashcode und Equals bereits implementiert sind, und es mir schwer fällt, mir vorzustellen, wie und noch schwieriger es ist, sich vorzustellen, warum Sie diese Implementierung ändern würden. –

+0

@JensSchauder: Mit Eclipse, um 'hashCode' und' equals' automatisch zu generieren, gab es eine Warnung, dass 'hashCode' und' equals' nicht für 'Class' definiert sind. Das hat mich besorgt, ob es eine gültige Warnung ist und ich sollte etwas dagegen tun. – Cratylus

+0

Ich weiß nicht, was Sie zu tun versuchen, aber "Klasse" ist eine Klasse, die selbst Teil von Java ist. Sie können nichts dafür implementieren. Wie lautet der vollständige Name der Quelldatei, in der Sie versuchen, hashCode und equals hinzuzufügen? –

Antwort

8

Die Implementierung von hashCode und equalsjava.lang.Class erbt von java.lang.Object sinnvoll ist und in der Regel angemessen, da alle Instanzen einer Klasse garantiert das gleicheClass Objekt aus getClass(), dh

new Integer(2).getClass() == new Integer(3).getClass(); 

Dies ist etwas zurück begraben in den Dokumenten; die javadoc of getClass() schreibt:

Returns:

Die Klasse-Objekt, das die Laufzeitklasse dieses Objekt darstellt. Auch

Siehe:

Literale, Abschnitt 15.8.2 der Java ™ Language Specification.

That section schreibt:

Eine Klasse wörtliche auswertet auf das Klassenobjekt für den genannten Typen (oder für nichtig), wie von der Definition Klassenlader definiert (Kapitel 12.2) der Klasse der aktuellen Instanz .

und section 12.2 schreiben:

Güter erzogene Klasse Lader pflegt diese Eigenschaften:

  • die gleichen Namen, eine gute Klassenlade Da sollte immer gibt das gleiche Klassenobjekt.
  • ...

Ein böswilliger Class Loader diese Eigenschaften verletzen könnte. Es konnte jedoch die Sicherheit des Typsystems nicht untergraben, weil die Java Virtual Machine dagegen wehrt.

Und ja, wenn die gleiche Klassendefinition von verschiedenen Klassenladern geladen wird, sind die Klassenobjekte nicht gleich. Da die Runtime diese als unabhängige Klassen behandelt (die zufällig denselben Namen haben, aber ansonsten nicht ähnlich, geschweige denn binärkompatibel sein müssen), ist dies normalerweise erwünscht.

+0

Randnotiz dazu: Anwendungen wie Tomcat verwenden einen hierarchischen Classloader und das kann Sie beißen. Tomcat gibt all seinen Anwendungen einen eigenen Classloader-Stack. –

0

Die Methode String getName() gibt eine eindeutige String-Darstellung der Klasse zurück. Sie können diese Zeichenfolge für equals/hashCode als normale Zeichenfolge verwenden, wenn Ihr Programm nicht mehr als einen Klassenlader verwendet.

+0

Aber ich tue nicht 'Karte , T>' .Meine Frage ist, wenn 'Klasse ' ist ** Teil ** eines Schlüssels.Nicht der Schlüssel selbst – Cratylus

+0

@Cratylus Die Antwort ist die gleiche; Sie verwenden getName(), das eine eindeutige String-Repräsentation des Klassenobjekts zurückgibt; Sie verwenden diese Zeichenfolge in Hashing/equals, als wäre es ein String-Instanzfeld. – m3th0dman

Verwandte Themen