2013-05-22 6 views
7

Ich habe eine Klasse mit javap dekompilierten und ich habe einige Duplikate im Constant Pool Abschnitt, so zu sehen:Java-Klasse konstante Pool-Duplikate?

#19 = Class    #350   // java/lang/StringBuilder 
... Some other class constants here 
#318 = Class    #350   // java/lang/StringBuilder 

Methodrefs nur einer von ihnen beziehen:

#20 = Methodref   #19.#351  // java/lang/StringBuilder."<init>":()V 
#22 = Methodref   #19.#353  // java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 
#24 = Methodref   #19.#355  // java/lang/StringBuilder.append:(Ljava/lang/Object;)Ljava/lang/StringBuilder; 
#25 = Methodref   #19.#356  // java/lang/StringBuilder.toString:()Ljava/lang/String; 
#110 = Methodref   #19.#445  // java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder; 

Ist diese Klasse korrekt nach The class File Format? Ich dachte, dass jede Klasse nur einmal erwähnt wird und später durch ihren Index im Bytecode-Teil referenziert wird.

$ javac -version 
javac 1.7.0_15 

Eine andere merkwürdige Sache ist in der Quelle der Klasse Pool.java den Constant Pool in Javac darstellt. Dies besagt, dass es kein Objekt in den Pool legt, wenn es bereits vorhanden ist (mit Hilfe einer HashMap). Ich frage mich, ob die equals()/hashCode() -Methoden dieser Klassen korrekt implemented sind.

Antwort

1

Sie haben Recht. Constant pool erfordert doppelte Einträge. Eine Klasse sollte nur 1 Eintrag im Konstantenpool haben.

Dies scheint definitiv ein Fehler zu sein. Sieh dir das an. Jemand hat dies als Fehler protokolliert und es bestätigt worden >>http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6746955

Antwort Aktualisiert:

Eine weitere Sache, ich möchte hier darauf hinweisen, dass das Hinzufügen doppelte Einträge keinen Sinn machen, weil es das erhöht Byte-Größe der Klassendatei, die den Hauptzweck der Kompaktheit, Portabilität und schnelleren Netzwerkmobilität der Java-Klassendatei zerstört. Die Klassendatei sollte so kompakt wie möglich sein.

Übrigens, die Klassendatei ist gültig, da sie dem definierten Klassendateiformat entspricht. Aber es ist kein idealer.

Als ich zu vergessen, Ihre zweite Frage beantworten:

JVM ordnet ähnlich Objekte den gleichen Hash-Code suchen, aber immer noch werden sie unterscheiden. JVM erstellt niemals zwei identische Objekte, es sei denn beide beziehen sich auf dasselbe Objekt. Hashcode ist nichts anderes als ein Partitionssystem. Ähnlich aussehende Objekte werden in derselben Partition platziert, so dass die Verfahrzeit bei der Suche nach einem bestimmten Objekt geringer wird. Hashcode ist nichts anderes als ein Zeiger auf diese kleine Partition.

Nur weil es nicht möglich ist, jedem neuen Objekt einen eindeutigen Hashcode zuzuordnen (da die Anzahl der Objekte die mögliche Anzahl der eindeutigen Hashcode-Erstellung übersteigen kann. Siehe mögliche Kollision im Hashalgorithmus), finden Sie möglicherweise unterschiedliche Objekte mit demselben Hashcode . Aber hier ist die Sache, 2 Objekte, die auf die gleiche Referenz im Speicher zeigen, müssen den gleichen Hashcode haben.

So, Moral der Geschichte, JVM stellt sicher, dass zwei verschiedene Objekte nie identisch sein können, selbst wenn ihre hashcodes sind.

+0

Haben Sie das betrachten Fehler, den Sie verlinkt haben? Es wurde im Jahr 2008 gemeldet, und die letzte Aktivität war vor 2 Jahren. Wäre es tatsächlich kaputt, wäre es längst repariert worden. – cHao

+0

Ich meinte nicht, wie alt es war. Ich bezog mich auf diesen Fehler und die Anerkennung davon. Ich wollte sagen, das ist in der Tat ein Fehler. –

+0

Es ist eine Ineffizienz .... aber es ist nicht falsch. – cHao

3

Wie ich aus der JVM-Spezifikation verstehe, gibt es keine solche Einschränkung, die doppelte Einträge im konstanten Pool verhindert. Im Allgemeinen haben die Compiler, die die Klassendatei generieren, keine Duplikate. Aber selbst wenn die Klassendatei Duplikate enthält, sollte dies das erwartete Verhalten nicht beeinflussen.

Wie wurde die Klassendatei erstellt, die Sie dekompiliert haben?

0

Eine Anmerkung: nach JENKINS-22525 scheint es, dass während Klassendateien mit solchen Duplikate technisch legal sind, IBM J9 VM wird in einigen Fällen ihre innere Klassen verweigern beobachtet zu laden, mit

java.lang.IncompatibleClassChangeError: incompatible InnerClasses attribute between …