How to Change Method Behaviour Through Reflection

How to change method behaviour through reflection?

Sounds like a weird requirement...

Anyway, reflection does not allow you to change code behaviour, it can only explore current code, invoke methods and constuctors, change fields values, that kind of things.

If you want to actually change the behaviour of a method you would have to use a bytecode manipulation library such as ASM. But this will not be very easy, probably not a good idea...

Patterns that might help you :

  • If the class is not final and you can modify the clients, extend the existing class and overload the method, with your desired behaviour. Edit : that would work only if the method were not static !
  • Aspect programming : add interceptors to the method using AspectJ

Anyway, the most logical thing to do would be to find a way to modify the existing class, work-arounds will just make your code more complicated and harder to maintain.

Good luck.

How to modify or substitute private method in a java class

Modify & replace:

One option is to mask the class with a modified copy (modify code, recompile code, add modified classes to the classpath before patched classes), similar to the approach used here to inspect how a normally unavailable method works.

If you do not have sources to modify, you can "reverse" almost any .class file into more-or-less readable source code using decompilers. Notice that, depending on licensing, you may not have permission to do so and/or to redistribute your changes.

Patch via agent:

You can also patch the methods using the -javaagent:<jarpath>[=<options>] commant-line option. The "agent" is a jar that gets to modify loaded classes and alter their behaviour. More information here.

Mock:

If you have control over where the methods are called, you can replace the target instance with a stubbed version. Libraries such as Mockito make this very, very easy:

LinkedList mockedList = mock(LinkedList.class);
// stubbing appears before the actual execution
when(mockedList.get(0)).thenReturn("first");

Even though Mockito does not support mocking private methods natively (mostly because it is considered bad manners to look at other classes' privates), using PowerMock allows you to do so (thanks, @talex).

Using reflection to modify the structure of an object

In java, reflection is not fully supported as defined by the wikipedia.

Only Field.setAccessible(true) or Method.setAccessible(true) really modifies a class, and still it only changes security, not behaviour.

Frameworks like e.g. hibernate use this to add behaviour to a class by e.g. generating a subclass in bytecode that accesses private fields in the parent class.

Java is still a static typed language, unlike javascript where you can change any behaviour at runtime.

Is it possible to modify methods of an object instance using reflection

There is no builtin way of doing this. And although you can do that using the PECL extension called runkit, I would strongly recommend finding another solution. Changing the implementation of functions you can't know anything about is very dangerous and might lead to bugs where debugging a single such bug can take longer than writing the if (is_null(... statements for all your functions.

BTW: don't use is_null(), since you might fetch null values from the database over and over again. You should store the fetched values in a separate variable.

Using reflection to modify the structure of an object

In java, reflection is not fully supported as defined by the wikipedia.

Only Field.setAccessible(true) or Method.setAccessible(true) really modifies a class, and still it only changes security, not behaviour.

Frameworks like e.g. hibernate use this to add behaviour to a class by e.g. generating a subclass in bytecode that accesses private fields in the parent class.

Java is still a static typed language, unlike javascript where you can change any behaviour at runtime.



Related Topics



Leave a reply



Submit