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

…衆ロ難τιáo~ 提交于 2019-11-27 04:20:40

问题


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).


回答1:


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




回答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




回答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.




回答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.




回答5:


If I got it right, the main problem that concerns you is how to pass a static method delegate (like in C#), through the instance interface method.

You can check this article: A Java Programmer Looks at C# Delegates, which shows you how to get a reference to your static method and invoke it. You can then create a wrapper class which accepts the static method name in its constructor, and implements your base class to invoke the static method from the instance method.



来源:https://stackoverflow.com/questions/1054777/java-reflection-how-do-i-override-or-generate-methods-at-runtime

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!