2010-05-21 20 views
1

Le problème est que je dois créer dans l'exécution d'une classe comme ceci:Création d'une classe java avec des champs annotés dans l'exécution

public class Foo { 
    @Bar int value0; 
    @Bar int value1; 
    @Bar int value2; 
.... 
} 

avec le nombre de champs étant décidé à l'exécution. Je regardais Javassist, et là vous pouvez créer une nouvelle classe, et ajouter des champs, mais je n'ai pas trouvé un moyen d'annoter ces champs.

+0

Je serais intéressé de savoir pourquoi vous ne pouvez pas utiliser un tableau. – Glenn

+0

J'utilise la bibliothèque qui l'exige. La bibliothèque était destinée à être utilisée pour les objets fixes, mais j'ai besoin de plus de flexibilité pour les générer lors de l'exécution. – Sarmun

Répondre

5

Vous pouvez utiliser une bibliothèque de manipulation de bytecode comme ASM:

import java.lang.reflect.Field; 
import java.util.Arrays; 
import org.objectweb.asm.ClassWriter; 
import org.objectweb.asm.FieldVisitor; 
import org.objectweb.asm.Opcodes; 
public class a { 
    public static void main(String[] args) throws Exception { 
    Class<?> klass = new ClassLoader(a.class.getClassLoader()) { 
     public Class<?> defineClass() { 
     ClassWriter cw = new ClassWriter(0); 
     cw.visit(Opcodes.V1_6, Opcodes.ACC_PUBLIC + Opcodes.ACC_SUPER, 
      "Foo", null, "java/lang/Object", null); 
     for (int i = 0; i < 3; i++) { 
      FieldVisitor fv = cw.visitField(0, "value" + i, "I", null, null); 
      fv.visitAnnotation("LBar;", true).visitEnd(); 
     } 
     cw.visitEnd(); 
     byte[] bytes = cw.toByteArray(); 
     return defineClass("Foo", bytes, 0, bytes.length); 
     } 
    }.defineClass(); 

    for (Field f : klass.getDeclaredFields()) { 
     System.out.println(f + " " + Arrays.toString(f.getAnnotations())); 
    } 
    } 
} 

Sortie:

int Foo.value0 [@Bar()] 
int Foo.value1 [@Bar()] 
int Foo.value2 [@Bar()] 
+0

Comment faire ceci à une classe déjà chargée? – Adelin