我正在寻找一种方法,通过重写字节代码和重新加载类来动态地向线程添加字段,但不确定是否可行。欢迎任何指点。我找到了一些关于修改和加载类的信息,我知道 JRebel 可以无缝地热交换您的代码,但不确定这里是否适用相同的方法/工具。
这里的动机是探索理论上更好的线程局部对象替代方案。如果该方法有效,我应该能够用注释替换线程本地,结果应该优于当前的 JDK 实现。
PS:请救救我“万恶之源”
阐明用例:
假设我有一个带有 ThreadLocal 的类:
class A {
ThreadLocal<Counter> 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()
}
最佳答案
目前不可能在运行时重新定义一个类,这样重新定义将导致新的方法或字段。这是因为扫描堆中所有现有实例并转换它们 + 它们的引用 + 潜在的不安全字段偏移基更新程序(如 AtomicFieldUpdater)所涉及的复杂性。
此限制可能会作为 JEP-159 的一部分解除但正如在 concurrency-interest 邮件组中讨论的那样,这是一个影响很大的变化,因此可能永远不会发生。
使用 Javaassist/similar 将允许将类转换为具有新方法/字段的新类。此类可以由 ClassLoader 加载并在运行时使用,但它的定义不会替换现有实例。因此,将不可能使用此方法结合代理来重新定义类,因为仪器重新定义是有限的:“重新定义可能会更改方法体、常量池和属性。重新定义不得添加、删除或重命名领域……”见here .
所以现在,不。
关于java - 如何即时修改 java.lang 类?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16986206/