如何动态修改 java.lang 类?

我正在寻找一种方法,通过重写字节代码并重新加载类来动态地将字段添加到线程中,不确定这是否可能。欢迎任何指点。我发现了一些关于修改和加载类的信息,我知道JRebel可以无缝地热交换你的代码,但不确定相同的方法/工具是否适用于这里。

这里的动机是探索一种理论上更好的线程局部对象替代方案。如果该方法有效,我应该能够用注释替换线程本地,并且结果应该优于当前的JDK实现。

PS:请拯救我“一切邪恶言论的根源”

澄清用例:

想象一下,我有一个带有ThreadLocal的类:


class A {
   ThreadLocal&ltCounter&gt counter;
   ...
   counter.get().inc()
}

我想用注释替换它:


class A {
   @ThreadLocal
   Counter counter;
   ...
   counter.inc()
}

但是,我不想生成上面的代码,而是要改变Thread,以便Thread现在将具有一个Acounter字段,实际代码将是:


class A {
   // Nothing here, field is now in Thread
   ...
   Thread.currentThread().Acounter.inc()
}

答案 1

目前,不可能在运行时重新定义类,以便重新定义将导致新的方法或字段。这是由于扫描堆中所有现有实例并转换它们+它们的引用+潜在的不安全字段偏移基础更新程序(如AtomicFieldUpdater)所涉及的复杂性。

此限制可能会作为 JEP-159 的一部分解除,但正如在并发利益邮件组中所讨论的那样,这是一个很大的影响更改,因此可能永远不会发生。

使用Javaassist/similar将允许将类转换为具有新方法/字段的新类。此类可以由 ClassLoader 加载并在运行时使用,但它的定义不会替换现有实例。因此,不可能将此方法与代理结合使用来重新定义类,因为检测重定义受到限制,因此:“重定义可能会更改方法主体,常量池和属性。重定义不得添加、删除或重命名字段...”看到这里

所以现在,不。


答案 2

如果你想在运行时改变“class”的行为,你可以试试javassist。接口就在这里


推荐