Question

En Java, est-il possible de créer une définition de classe à la volée, alors qu'une application est en cours d'exécution, puis créer un objet de cette classe?

Par exemple, une application en cours d'exécution lirait dans un fichier texte qui contient une liste des membres de la classe à inclure dans la nouvelle classe. L'application serait alors définir une définition de classe basée sur la liste des membres, puis insantiate il.

Était-ce utile?

La solution

Oui il est possible de le faire en théorie votre fichier de classe est un code d'octet qui est à la fin d'un tableau d'octets! vous pouvez ensuite utiliser la méthode defineClass (String, byte [], int, int) pour obtenir une instance de classe qui peut être utilisé pour instancier des objets par réflexion.

Dans la pratique, vous pouvez utiliser quelque chose comme Cglib ou javaassist .

Vous pouvez également utiliser la longue façon de générer le code Java dans un fichier, l'appel du compilateur, charger le fichier.

Autres conseils

Vous pouvez générer dynamiquement des classes en utilisant ASM

Vous pouvez le faire en écrivant le code pour votre nouvelle classe dans un fichier, puis d'invoquer le compilateur Java sur ce fichier et en utilisant un classloader pour charger dynamiquement cette classe dans votre application en cours d'exécution. Apache Tomcat fait pour ses pages JSP; il prend le code, fait quelques modifications, il enveloppe dans un bloc try / catch au milieu d'une classe, où il écrit alors le système de fichiers, compile et un classloader pour obtenir et poursuivre en justice pour répondre à des demandes.

Bien sûr, il est possible. Voir par exemple cette .

Peut-être le simple solution (en termes de ne nécessitant pas de bibliothèques supplémentaires) serait d'utiliser le Java API du compilateur qui vient avec Java 6. Vous venez juste être en mesure de générer le .java, compiler et exécuter une Class.forName () .

Peut-être un peu exagéré, Apache BCEL (Byte Code Engineering Library) peut être utilisé pour créer des fichiers class lors de l'exécution.

Bien que je ne l'ai pas essayé moi-même, en théorie, on pourrait alors créer une classe, le charger et instancier lors de l'exécution.

Oui, cela est possible.

Vous pouvez créer des classes avec Javassist lors de l'exécution par définir le corps de la classe et de faire javassist compiler votre nouvelle classe.

Javassist a un compilateur personnalisé qui crée bytecode en fonction de la définition de votre classe. Il a des façons particulières de gérer les choses, mais il est très facile et intuitif à utiliser cette bibliothèque.

Javassist est utilisé sur JBoss, et je crois que c'est une bonne référence:)

La même chose peut être réalisé avec BCEL , mais il est beaucoup plus difficile (mais de cette façon vous ont plus de contrôle sur ce qui est généré).

Vous pourriez probablement faire quelque chose comme ça avec JRuby, ou JPython ou Groovy si vous devez.

Si vous vous sentez particulièrement masochiste, vous pouvez regarder BCEL .

Si vous voulez Java et métaprogrammation, utilisez Groovy.

ASM est la bibliothèque de bytecode plus bas niveau pour Java, je suppose. Cela rend très difficile mais aussi très puissant. de comprendre vraiment comment la génération de bytecode Je recommande la lecture de la documentation de l'ASM ( PDF ) en Java fonctionne. Cette documentation explique également comment charger le bytecode dans le chargeur de classe (un autre sujet difficile à faire à droite).

Après cela, vous pouvez utiliser l'une des bibliothèques de niveau supérieur, si elle rend votre vie plus facile, et comprendre ce qu'ils font. Pour de nombreux cas, comme mandataires de production, le CGLIB est utile et simple à utiliser. Pour plus de puissance, beaucoup ont mentionné Javassist (paradis I » t utilisé -. CGLIB et ASM ont été bon pour moi)

Il y avait une question récente ici concernant compilation en mémoire qui devrait vous donner quelques conseils sur ce qu'il faut faire après avoir réussi à générer le code source.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top