web-dev-qa-db-fra.com

Comment changer le comportement d'une méthode par la réflexion?

J'ai une méthode statique dans un code hérité, qui est appelée par plusieurs clients. Je n'ai évidemment aucune option pour le remplacer ou changer de comportement via l'injection de dépendances. Je ne suis pas autorisé à modifier la classe existante.

Ce que je veux faire maintenant, c'est changer le comportement (cette méthode - avec la même signature et le même type de retour) en utilisant la réflexion.

C'est possible ? Sinon, un motif de conception peut-il me sauver?

Merci !

EDIT: Il y a une certaine confusion sur ce que je peux changer/modifier. Je ne peux changer aucune classe/méthode existante - mais je peux ajouter plus de classes au projet. Le mieux que je puisse faire avec les classes existantes est de les annoter. Tout cela est fait pour éviter de casser quoi que ce soit dans le code existant - ce qui signifie une série complète de tests pour un gros projet.

EDIT 2: Java.lang.Instrumentation n'est pas disponible pour Android - ou bien cela ressemble à un bon ajustement!

25
Jaguar

Cela ressemble à une exigence étrange ...

Quoi qu'il en soit, la réflexion ne vous permet pas de changer le comportement du code, elle ne peut qu'explorer le code actuel, invoquer des méthodes et des constucteurs, changer les valeurs des champs, ce genre de choses.

Si vous voulez réellement changer le comportement d'une méthode, vous devrez utiliser une bibliothèque de manipulation de bytecode telle que ASM. Mais ce ne sera pas très facile, ce n'est probablement pas une bonne idée ...

Modèles qui pourraient vous aider:

  • Si la classe n'est pas définitive et que vous pouvez modifier les clients, étendez la classe existante et surchargez la méthode, avec le comportement souhaité. Edit: cela ne fonctionnerait que si la méthode n'était pas statique!
  • Programmation Aspect: ajoutez des intercepteurs à la méthode en utilisant AspectJ

Quoi qu'il en soit, la chose la plus logique à faire serait de trouver un moyen de modifier la classe existante, les solutions de contournement rendront votre code plus compliqué et plus difficile à maintenir.

Bonne chance.

27
Pierre Henry

Je suppose que vous pourriez jeter un œil à la classe Instrumentation qui a une méthode redefineClasses(ClassDefintion classDefinition).

La redéfinition peut changer les corps de méthode, le pool constant et les attributs. La redéfinition ne doit pas ajouter, supprimer ou renommer des champs ou des méthodes, modifier les signatures des méthodes ou modifier l'héritage.

J'espère que cela t'aides.

Références: Javadoc

15
Dangling Piyush