Java reflection: How do I override or generate methods at runtime?

32,538

Solution 1

You can use something like cglib for generating code on-the-fly

Solution 2

In java6 has been added the possibility to transform any already loaded class. Take a look at the changes in the java.lang.instrument package

Solution 3

For interfaces there is java.lang.reflect.Proxy.

For classes you'll either need a third-party library or write a fair bit of code. Generally dynamically creating classes in this way is to create mocks for testing.

There is also the instrumentation API that allows modification of classes. You can also modify classes with a custom class loader or just the class files on disk.

Solution 4

I wrote an article for java.net about how to transparently add logging statements to a class when it is loaded by the classloader using a java agent.

It uses the Javassist library to manipulate the byte code, including using the Javassist compiler to generate extra bytecode which is then inserted in the appropriate place, and then the resulting class is provided to the classloader.

A refined version is available with the slf4j project.

Share:
32,538
ivan_ivanovich_ivanoff
Author by

ivan_ivanovich_ivanoff

!!! Netbeans 6.7 RELEASED !!! C is far better and easier than Java! Why? It is easier to use void pointers and to do pointer arithmetic, than explaining the basic concepts of OOP to a C programmer. Joke of the century: PHP is good, because it works... "PHP programming" is an oxymoron. There is no PHP programming. There is only PHP scriptkidding. There are two types of people who use PHP: - those who don't know other languages, - and those who HAVE TO use it Java is to JavaScript what Car is to Carpet. The LHC is the wrong answer to the technological singularity.

Updated on January 22, 2020

Comments

  • ivan_ivanovich_ivanoff
    ivan_ivanovich_ivanoff over 4 years

    It is possible in plain Java to override a method of a class programmatically at runtime (or even create a new method)?

    I want to be able to do this even if I don't know the classes at compile time.

    What I mean exactly by overriding at runtime:

    abstract class MyClass{
      public void myMethod();
    }
    
    class Overrider extends MyClass{
      @Override
      public void myMethod(){}
    }
    
    class Injector{
      public static void myMethod(){ // STATIC !!!
        // do actual stuff
      }
    }
    
    // some magic code goes here
    Overrider altered = doMagic(
        MyClass.class, Overrider.class, Injector.class);
    

    Now, this invocation...

    altered.myMethod();
    

    ...would call Injector.myMethod() instead of Overrider.myMethod().

    Injector.myMethod() is static, because, after doing "magic" it is invoked from different class instance (it's the Overrider), (so we prevent it from accessing local fields).