How to change method behaviour through reflection?
Как изменить поведение метода с помощью отражения?
У меня есть статический метод в некотором устаревшем коде, который вызывается несколькими клиентами. Очевидно, что у меня нет вариантов переопределить его или изменить поведение с помощью внедрения зависимостей. Мне не разрешено изменять существующий класс.
Что я хочу сделать сейчас, так это изменить поведение (этот метод - с той же сигнатурой и возвращаемым типом) с помощью отражения.
Возможно ли это? Если нет, может ли какой-либо шаблон проектирования спасти меня?
Спасибо!
РЕДАКТИРОВАТЬ : Есть некоторая путаница в том, что я могу изменить. Я не могу изменить ни один существующий класс / метод, но я могу добавить больше классов в проект. Лучшее, что я могу сделать с существующими классами, - это аннотировать их. Все это делается для того, чтобы ничего не нарушать в существующем коде, что означает полный цикл тестирования для большого проекта.
ПРАВКА 2: java.lang.Инструментарий недоступен для Android - иначе это звучит как подходящее!
Переведено автоматически
Ответ 1
Звучит как странное требование...
В любом случае, отражение не позволяет вам изменять поведение кода, оно может только исследовать текущий код, вызывать методы и конструкторы, изменять значения полей и тому подобное.
Если вы хотите на самом деле изменить поведение метода, вам придется использовать библиотеку манипулирования байт-кодом, такую как ASM. Но это будет не очень просто, вероятно, это плохая идея...
Шаблоны, которые могут вам помочь :
Если класс не является окончательным, и вы можете модифицировать клиентов, расширить существующий класс и перегрузить метод желаемым поведением. Редактировать : это сработало бы, только если бы метод не был статическим!
Аспектное программирование: добавьте перехватчики в метод с помощью AspectJ
В любом случае, логичнее всего было бы найти способ модифицировать существующий класс, обходные пути просто усложнят ваш код и его будет сложнее поддерживать.
Удачи.
Ответ 2
Я думаю, вы могли бы взглянуть на класс инструментирования, в котором есть метод redefineClasses(ClassDefintion classDefinition).
Переопределение может изменить тела методов, пул констант и атрибуты. Переопределение не должно добавлять, удалять или переименовывать поля или методы, изменять сигнатуры методов или изменять наследование.
Вы можете изменить поведение метода с помощью механизма динамических прокси в Java. Смотрите Это руководство. Оно будет проксировать все методы объекта. Вы можете переопределить только некоторые методы по имени метода, например:
public Object invoke(Object proxy, Method method, Object[] args)throws Throwable { if (method.getName().equals("put")) { // example for map methods.get(method.getName()).invoke(target, args); args[0] = "second"; // put again with "second" key Objectresult= methods.get(method.getName()).invoke(target, args);
return result; }
if (method.getName().equals("get")) { // example for map System.out.println("Method get"); // you implementation return methods.get(method.getName()).invoke(target, args); }
return methods.get(method.getName()).invoke(target, args); // just do what initial method do }