java - 如何即时修改 java.lang 类?

标签 java classloader dynamic-class-loaders dynamic-class-creation

我正在寻找一种方法,通过重写字节代码和重新加载类来动态地向线程添加字段,但不确定是否可行。欢迎任何指点。我找到了一些关于修改和加载类的信息,我知道 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/

相关文章:

java - Microsoft Translator API Java,如何使用 Azure 获取客户端新 ID

java - 想法tomcat8部署总是404

java - ANT - Java ClassLoader 找不到类

Java : Executing a method of an arbitrary class in a sub package

java - JAVA动态类加载的性能开销

java - 在Java中,如何在不提前知道名称的情况下加载类?

java - Swing JLabel 缺少字符

java - 在 Java 中从 Internet 获取数据

java - 如何从两个单独的类加载器创建 java.lang.reflect.Proxy?

java - ClassLoader.getSystemClassLoader().getResource() 在 servlet 容器和测试环境中的不同行为