首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何动态修改java.lang类?

如何动态修改java.lang类?
EN

Stack Overflow用户
提问于 2013-06-07 22:11:35
回答 6查看 5.5K关注 0票数 16

我正在寻找一种方法,通过重写字节码和重新加载类来动态地向Thread添加字段,不确定这是否可能。欢迎任何指导者。我发现了一些关于修改和装入类的信息,我知道JRebel可以无缝地热插拔你的代码,但我不确定同样的方法/工具是否适用于这里。

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

附言:请保存我的“一切邪恶言论的根源”

澄清用例:

假设我有一个带有ThreadLocal的类:

代码语言:javascript
复制
class A {
   ThreadLocal<Counter> counter;
   ...
   counter.get().inc()
}

我想用一个注解来代替它:

代码语言:javascript
复制
class A {
   @ThreadLocal
   Counter counter;
   ...
   counter.inc()
}

但我不想生成上面的代码,而是修改Thread,使Thread现在有一个Acounter字段,实际代码为:

代码语言:javascript
复制
class A {
   // Nothing here, field is now in Thread
   ...
   Thread.currentThread().Acounter.inc()
}
EN

回答 6

Stack Overflow用户

回答已采纳

发布于 2013-06-18 15:06:48

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

这一限制可能会作为JEP-159的一部分取消,但正如在并发兴趣邮件组中所讨论的,这是一个重大的影响更改,因此可能根本不会发生。

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

因此,就目前而言,没有。

票数 11
EN

Stack Overflow用户

发布于 2013-06-07 23:02:24

如果你想改变“类”在运行时的行为,你可以尝试javassist。接口为here

票数 5
EN

Stack Overflow用户

发布于 2013-06-18 02:48:28

这似乎是一个使用正确的工具来完成工作的问题。这里提出了一个类似的问题:Another Stack Overflow Question和Javaassist字节码操作库是一种可能的解决方案。

但没有进一步详细说明为什么会尝试这样做,似乎真正的答案是使用正确的工具来完成这项工作。例如,使用Groovy the ability to dynamically add methods to the language

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/16986206

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档