Java 反射:如何在运行时重写或生成方法?

发布于 2024-07-25 20:13:58 字数 766 浏览 7 评论 0原文

在普通 Java 中可以重写类的方法 在运行时以编程方式(甚至创建一个新方法)?

即使我在编译时知道这些类,我也希望能够做到这一点。

我所说的在运行时重写的确切含义是:

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

现在,此调用...

altered.myMethod();

...将调用 Injector.myMethod() 而不是 Overrider.myMethod()

Injector.myMethod() 是静态,因为,在做了“魔术”之后 它是从不同的类实例调用的(它是 Overrider), (所以我们阻止它访问本地字段)。

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

南风几经秋 2024-08-01 20:13:58

您可以使用诸如 cglib 之类的东西来动态生成代码

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

静若繁花 2024-08-01 20:13:58

java6 中添加了转换任何已加载类的可能性。 查看 java 中的更改 .lang.instrument包

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

挽梦忆笙歌 2024-08-01 20:13:58

对于接口,有java.lang.reflect.Proxy

对于类,您要么需要第三方库,要么编写大量代码。 一般以这种方式动态创建类就是创建mock来进行测试。

还有允许修改类的检测API。 您还可以使用自定义类加载器或仅修改磁盘上的类文件来修改类。

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.

握住你手 2024-08-01 20:13:58

我写了一个 java.net 文章,介绍如何在类加载器使用 java 代理加载类时透明地向类添加日志记录语句。

它使用 Javassist 库来操作字节码,包括使用 Javassist 编译器生成额外的字节码,然后将其插入到适当的位置,然后将生成的类提供给类加载器。

slf4j 项目提供了改进的版本。

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.

沉睡月亮 2024-08-01 20:13:58

如果我没猜错的话,您关心的主要问题是如何通过实例接口方法传递静态方法委托(就像在 C# 中一样)。

您可以查看这篇文章: Java 程序员看看 C# 委托(已存档),它向您展示了如何获取对静态方法的引用并调用它。 然后,您可以创建一个包装类,该类在其构造函数中接受静态方法名称,并实现基类以从实例方法调用静态方法。

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 (archived), 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文