Java-interne Klasseninkonsistenz zwischen Deskriptor- und Signaturattribut? (Klassendatei)

8

Ich versuche zu verstehen, ob es in der Spezifikation einen Grund für die Diskrepanz zwischen Java-Deskriptoren und Signaturen für innere Klassen gibt. (Ich schaue hier direkt auf den Inhalt der Klassendateien, aber ich benutze javap zur Veranschaulichung).

(nb Ich habe dies auf JDK 1.6.0_33 und 1.7.0_05 versucht, beide haben das gleiche Problem wenn sie mit javap von Java 7 betrachtet werden - java 6's javap scheint keine generischen anzuzeigen Signatur-Info, wie Seans Antwort unten.)

Update: Danke an diejenigen, die diskutieren - meine Meinung ist

  • Der Deskriptor (der keine generischen Informationen enthält) ist korrekt.
  • Die Signatur (die ein Attribut der Methode ist und generische Informationen enthält) ist falsch. Der relevante ConstPool-Eintrag für SIGNATURE des & lt; init & gt; Methode ist "ConstantUTF8 [(Ljava / util / list & lt; TE; & gt;) V]"
  • JavaP in Java 6 betrachtet nicht die Signatur, nur den Deskriptor. (Meine Vermutung!)

Falls jemand sich wundert, dass ich dies ohne JAVAP benutze und nur die Klassendateien selbst betrachte, benutze ich nur javap um es zu zeigen. (Es ist also unwahrscheinlich, dass es sich um einen Javap-Fehler handelt).

Überlegen Sie:

%Vor%

vs

%Vor%

Wenn Sie die Ausgabe von javap -cs auf den inneren Klassen betrachten, sind sie überraschend anders!

public org.benf.cfr.tests.InnerClassTest1 $ Inner1 ( org.benf.cfr.tests.InnerClassTest1, java.util.List);  Unterschrift: (Lorg / benf / cfr / Tests / InnerClassTest1; Ljava / util / Liste;) V

vs

public org.benf.cfr.tests.InnerClassTest2 $ Inner1 (java.util.List & lt; E & gt;);  Signatur: (Lorg / benf / cfr / Tests / InnerClassTest2; Ljava / util / Liste;) V

... der eine, der Generics verwendet, fehlt der implizite Parameter für die äußere Klasse! (es ist korrekt in InnerClassTest1 vorhanden).

Ich kann nichts in der Dokumentation der Klassendatei finden, um dies zu erklären - weiß jemand, warum das so sein könnte?

Danke!

Lee.

Aktualisieren -

Ich habe Beispieldateien unter Ссылка

platziert

Nachdem ich Seans Antwort unten gegeben habe, habe ich versucht, javap auf Java 6 zu verwenden, und ich sah identische Ausgaben für beide, ohne generische Informationen - das lässt mich glauben, dass Java 6's javap keine vollständigen Signaturinformationen anzeigt?

Die genaue Ausgabe, die ich mit javap auf 1.7.0_05-b06 erhalte, ist

%Vor%     
lab27 28.02.2013, 08:43
quelle

2 Antworten

1

Unter Verwendung des obigen Codes und unter Verwendung von JDK 1.6.0_33 erhalte ich die folgende Ausgabe:

%Vor%

und die einzigen Unterschiede sind, dass meine Implementierung (um den Code kompilieren zu lassen):

%Vor%

und die Tatsache, dass Ihr Paketname wahrscheinlich anders ist (org.benf.cfr.tests?).

Abgesehen davon ist meine Ausgabe ziemlich gleich. Gibt es weitere Unterschiede im Code, die erklären könnten, was Sie sehen? Von dem, was ich über den Kompilierungsprozess und die Klassendateien weiß, würde ich keinen Unterschied in der Ausgabe erwarten.

Gute Frage - interessant zu finden, warum Sie das sehen

    
Sean Landsman 28.02.2013 11:30
quelle
1

Verwenden von JavaP auf InnerClassTest2$Inner1 gibt

%Vor%

Zerlegen mit Krakatau gibt

%Vor%

Wie Sie sehen können, zeigt die Krakatau-Ausgabe, dass der Deskriptor tatsächlich korrekt ist, aber aus irgendeinem Grund zeigt JavaP ihn nicht an. Eine Sache über JavaP ist, dass es versucht, die Ausgabe so anzuordnen, dass sie eher wie Java aussieht. Vielleicht ist dies ein neues Feature, das in JDK7 eingeführt wurde und versucht, disassemblierte Generics eher wie Java aussehen zu lassen, indem die Compiler-hinzugefügten Parameter versteckt werden. Leider macht dies Javap (noch mehr) nutzlos, um zu sehen, was wirklich da ist.

Interessanter Fang!

    
Antimony 28.02.2013 13:21
quelle

Tags und Links