64 votes

Peut une classe Java ajouter une méthode à lui-même au moment de l'exécution?

Peut une classe d'ajouter une méthode à lui-même au moment de l'exécution (comme à partir d'un static de l'îlot), donc si quelqu'un est d'effectuer une réflexion sur cette classe, ils vont voir que la nouvelle méthode, même si elle n'était pas définie au moment de la compilation?

Arrière-plan:

Un cadre que je suis en utilisant prévoit Action classes à définir qui ont un doAction(...) méthode, par convention. Le cadre inspecte ces classes au moment de l'exécution pour voir quel type de paramètres sont disponibles dans leur doAction() méthode. Par exemple: doAction(Chaîne a, Entier b)

J'aimerais que chaque classe pour pouvoir en programmant générer ses doAction() méthode avec des paramètres différents, juste-à-temps quand il est inspecté. Le corps de la méthode peut être vide.

61voto

Andreas_D Points 64111

Ce n'est pas simple. Une fois qu'une classe est chargée par un chargeur de classe, il n'y a aucun moyen de changer les méthodes de classes chargées. Lorsqu'une classe est demandé, un chargeur de classe de charge et lien il. Et il n'existe aucun moyen (avec Java) pour changer liés au code ou à ajouter/supprimer des méthodes.

Le seul truc qui me vient à l'esprit est le jeu avec les chargeurs de classe. Si on supprime un classloader personnalisé, puis les classes chargé par le chargeur de classe doivent être effacées ou inaccessibles trop. L'idée qui me vient à l'esprit est de

  1. mettre en œuvre un classloader personnalisé
  2. chargement de la dynamique de classe avec qui classloader personnalisé
  3. si nous avons une version mise à jour de cette classe,
  4. supprimer le classloader personnalisé et
  5. chargement de la nouvelle version de cette classe avec une nouvelle instance de la classloader personnalisé

Je laisse ça comme de la nourriture pour la pensée, ne peut pas le prouver, si cela conduit à une solution ou si nous avons des pièges.

Une réponse simple à la question: Non, nous ne pouvons pas changer une classe chargée comme nous pouvons modifier le contenu des champs de la réflexion. (on ne peut pas ajouter ou supprimer des champs trop).

25voto

DrGranit Points 111

Andres_D est de droite, on peut très bien le faire à l'aide personnalisée de chargement de classe, voici un guide détaillé sur la façon de le faire: http://www.javaworld.com/javaworld/jw-06-2006/jw-0612-dynamic.html?page=1

L'article explique comment écrire dynamique de code Java. Il traite d'exécution compilation du code source, la classe de rechargement, et l'utilisation du Proxy modèle de conception pour apporter des modifications à une classe dynamique transparente à son appelant.

En fait, chercheur en Autriche ont écrit une JVM qui permet même de recharger les classes avec différents type de hiérarchies. Ils ont atteint cet objectif par l'utilisation de thread existant enregistrer des points de générer un état complet du côté de l'univers " d'un objet et toutes ses références relatives et référencé le contenu, puis une fois entièrement remanié avec toutes les modifications nécessaires il suffit de remplacer dans tous changé de classe. [1] Voici un lien vers leur projet http://ssw.jku.at/dcevm/ l'oracle de parrainage rend certainement pour d'intéressantes spéculations sur les projets d'avenir.

Moins intrusif des changements à la méthode organes et les champs sont d'ores et déjà possible dans le standard de la machine virtuelle java à l'aide de l'échange à Chaud des capacités de la JPDA introduit dans Java 1.4:
docs.oracle.com/javase/1.4.2/docs/guide/jpda/enhancements.html#hotswap

Je ne suis pas sûr de savoir si c'était la première mais ce Soleil employé du papier à partir de 2001 semble être l'une des premières propositions de mentionner les capacités de ce dernier à la Hot-Swap. [2]

RÉFÉRENCE

[1] T. Würthinger, C. Wimmer, et L. Stadler, "Code Dynamique de l'Évolution de Java", présenté lors de la 8e Conférence Internationale sur les Principes et la Pratique de la Programmation en Java, Vienne, 2010.

[2] M. Dmitriev, "Vers flexible et sûre de la technologie pour l'exécution de l'évolution du langage java applications", dans OOPSLA Atelier sur l'Ingénierie Complexe de Systèmes Orientés Objet pour l'Évolution, 2001.

10voto

Ryan Stewart Points 46960

Je n'ai jamais rien essayé de tout à fait comme moi-même, mais vous devriez avoir un coup d'oeil à l'ASM, cglib, et Javassist.

5voto

Jesper Points 65733

Non, ce n'est pas (facilement) possible en Java.

Il semble que vous essayez d'utiliser Java comme si c'est un langage de programmation dynamique. Par exemple, Ruby a l'ouverture des classes: vous pouvez ajouter et supprimer des méthodes de classes Ruby au moment de l'exécution. En Ruby, vous pouvez également avoir une "méthode manquant" de la méthode dans votre classe, qui sera appelée lorsque vous essayez d'appeler une méthode qui n'existe pas dans la classe. Une telle chose n'existe pas en Java.

Il existe une version de Ruby, qui tourne sur la JVM, JRuby, et il y a à faire, très difficile astuces pour faire ouvrir les classes à travailler sur la JVM.

3voto

Peter Lawrey Points 229686

Vous pouvez avoir un doAction méthode qui fait tout ce que vous voulez que la méthode générée à faire. Est-il une raison pour laquelle il doit être généré ou peut-il être dynamique?

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X