2010-07-14 8 views
12

Einfache Definition von Getter und Setter ist einfach mit Asm (und glücklicherweise wird es sogar in ihren FAQ erklärt). Aber eine Sache, die nicht erwähnt wird und für die ich keine Dokumentation finden konnte, ist, wie man diese mit generischen Typinformationen implementiert.Generieren von Methoden mit generischen Typen mit Asm bytecode generator (ClassWriter)

Ich bin tatsächlich in der Lage, generische Art Informationen selbst ganz einfach zu bestimmen (da Code wird die bestehenden Felder und/oder Methoden und vollständige generische Art Handhabung und Auflösung besteht). Ich muss nur generics Version für Typen generieren, die generischen Typ enthalten haben.

Ich hoffe, dies ist so einfach wie das Ändern der Signatur Asm ClassWriter/MethodVisitor Aufrufe, aber einige Kommentare in der Dokumentation zeigen, es könnte nicht so einfach sein (wie Generika Informationen in Bit anders als normale Informationen gespeichert).

BEARBEITEN: sieht aus wie Eintrittspunkt ist "ClassWriter.visitField/Method (...., Zeichensignatur) - beachten Sie, dass es" Beschreibung "ist, die normale nicht-generische Klasseninformationen enthält, aber Begriff" Signatur " (in JLS) bezieht sich speziell auf Generika - einschließlich Typ Informationen.

Antwort

8

Sie können die Signatur mit der Klasse SignatureWriter von ASM erstellen

Beispiel: Angenommen, Sie die Signatur für diese Methode schreiben wollen:

SignatureWriter signature = new SignatureWriter(); 
signature.visitFormalTypeParameter("K"); 

// Ensure that <K> extends java.lang.Object 
{ 
    SignatureVisitor classBound = signature.visitClassBound(); 
    classBound.visitClassType(Type.getInternalName(Object.class)); 
    classBound.visitEnd(); 
} 

// The parameter uses the <K> type variable 
signature.visitParameterType().visitTypeVariable("K"); 

// The return type uses the void primitive ('V') 
signature.visitReturnType().visitBaseType('V'); 

signature.visitEnd(); 

String signatureString = signature.toString(); 

Welche äquivalent zu: I

String signatureString = "<K:Ljava/lang/Object;>(TK;)V;" 
+0

Das ist nützlich, danke. Mein spezifisches Problem scheint jetzt zu sein, dass die resultierende Signatur irgendwie nicht korrekt in die Klassendatei geschrieben ist, obwohl ich das korrekte Format verwende (soweit ich weiß). Aber vielleicht sollte ich mit SignatureWriter überprüfen, um sicherzustellen, dass ... – StaxMan

+1

@StaxMan: Ich hatte auch meine Mühe damit. Vielleicht hilft dieser Artikel: [Classworking Toolkit: Generics with ASM] (http://www.ibm.com/developerworks/java/library/j-cwt02076.html) –

+0

Ah! Ich habe endlich das eigentliche Problem in meinem Code gefunden: Ich hatte das Argument V1_2 in ClassVisitor.visit(); und dies muss V1_5 oder höher sein, damit Generika (und Annotationen) unterstützt werden. Danke für Ihre Hilfe! – StaxMan

-1

Meiner Erfahrung nach die meisten On-the-Fly-Bytecode-Generierung Bibliotheken haben keine gute Unterstützung für generische Typen, aber gelöschte Klassen funktionieren gut (es sei denn, Sie wollen Schauen Sie sich diese Klassen später natürlich an.)

+1

Leider

public <K> void doSomething(K thing) 

Sie diesen Code verwenden könnte Insbesondere brauchen Sie Introspektion - so wird die Verwendung von Bibliothek tatsächlich Serialisierer und Deserialisierer konstruieren. : -/ Ja, codewise Löschung würde ok funktionieren ... und ich muss möglicherweise nur eine andere Möglichkeit finden, die Dinge funktionieren zu lassen, vielleicht durch Hinzufügen neuer Arten von Anmerkungen, um Signaturen effektiv zu replizieren. – StaxMan