2009-06-12 6 views

Répondre

4

Je ne suis pas au courant d'un outil qui fait automatiquement. J'utiliserais probablement la classe org.objectweb.asm.util.ASMifierClassVisitor pour comprendre la relation entre les signatures et les appels API ASM.

Pour une classe contenant ce code:

public void foo1(Object o1, String s2) { 
    } 

... l'outil va générer:

mv = cw.visitMethod(ACC_PUBLIC, "foo1", 
    "(Ljava/lang/Object;Ljava/lang/String;)V", null, null); 
mv.visitCode(); 
mv.visitInsn(RETURN); 
mv.visitMaxs(0, 3); 
mv.visitEnd(); 

Pour ce code:

public static final String[] foo2() { 
    return null; 
    } 

... il va générer :

mv = cw.visitMethod(ACC_PUBLIC + ACC_FINAL + ACC_STATIC, 
    "foo2", "()[Ljava/lang/String;", null, null); 
mv.visitCode(); 
mv.visitInsn(ACONST_NULL); 
mv.visitInsn(ARETURN); 
mv.visitMaxs(1, 0); 
mv.visitEnd(); 

Il ya des notes sur method signatures in the FAQ et il est utile si vous comprenez Java class nomenclature.

Notez que l'API ASM peut également être utilisée pour transformer un java.lang.reflect.Method en org.objectweb.asm.commons.Method. Puisque vous pouvez get the class à partir du java.lang.reflect.Method, vous pouvez utiliser ClassVisitor s/MethodVisitor s à inspect the methods.

+0

Eh bien, je cherchais un moyen d'obtenir directement de la réflexion api sans ré-analyser le fichier de classe en utilisant asm . La chose devient difficile avec la réflexion api pour génériques –

+0

OK, je pense que je comprends - je ne suis pas sûr qu'il y aurait une approche unique pour tous. Si une méthode renvoie une valeur, vous devez y ajouter une certaine logique pour la rendre valide (en supposant qu'elle ne soit pas abstraite). – McDowell

1

Je pense que j'essayais de faire quelque chose de très similaire (Generating methods with generic types with Asm bytecode generator (ClassWriter)).

De visitMethod de classe visiteur, je vois cette méthode comme:

public List<String> foobar(List<Integer> args, List<Boolean> args2); 

produira la description comme:

(Ljava/util/List;Ljava/util/List;)Ljava/util/List; 

(comme prévu, sans génériques info)

et signature comme :

(Ljava/util/List<Ljava/lang/Integer;>;Ljava/util/List<Ljava/lang/Boolean;>;)Ljava/util/List<Ljava/lang/String;>; 

(avec les génériques ajoutés)

donc il devrait être raisonnablement simple de générer une signature générique pour augmenter la description non générique. C'est assez similaire à la façon dont les informations génériques sont ajoutées dans la source, à l'exception des bizarreries introduites par le traitement des types primitifs à un seul caractère.

Je ne l'ai pas encore essayé, mais étant donné que visitMethod() de ClassWriter prend également la signature, j'espère que cela fonctionnera. :)

+0

Pour ce que cela vaut, alors que cela devrait apparemment fonctionner, il ne semble pas. Le problème est que ASM lui-même l'ajoute, et peut le voir, mais les méthodes de réflexion de la JVM ne semblent pas être trouvées pour une raison quelconque. : - / – StaxMan

0

Essayez d'utiliser printemps-asm bibliothèque (par exemple Type.GetType (String.class))

Questions connexes