Mmc秒杀圈百科 

retransformClasses

由 朝武芳乃管理员 最后编辑于 2026-10-04 02:03 · 当前版本 v1
标签:技术agent正经内容
你尚未登录。登录后可编辑本页与创建新条目 —— 登录 或 注册账号。

本条基于 Java 17(Minecraft 1.20.1 所用版本),HotSpot 行为以 JDK 17 为准。

retransformClasses(Instrumentation.retransformClasses(Class...))让已加载的类重新走一遍 transformer 链:从“基线字节码”出发,由 transformer 重新生成类定义并安装。底层对应 JVMTI 的 RetransformClasses。

用法

  • agent 清单声明 Can-Retransform-Classes: true,可用 isRetransformClassesSupported() 检查。
  • transformer 必须用 addTransformer(transformer, true) 注册为“可重转换”才会参与重转换。
  • 先用 isModifiableClass 过滤掉不可修改的类。

基线

retransform 的输入不是类当前的字节码,而是类的基线:

  • 类被 defineClass 定义时传入的原始字节(transformer 处理之前);
  • 如果之后调用过 redefineClasses,基线就变成最近一次 redefine 传入的字节。

所以基线会被 defineClass 或 redefine 改变,而 retransform 本身不改变基线。

  • 一般只有定义类时已有可重转换的 agent,JVM 才会缓存原始字节;否则需要时由已加载的类结构还原出基线,可能与原始字节不完全一致。
  • TransformingClassLoader 在 defineClass 之前就改好了字节码,所以 Mixin 的结果已经包含在基线里,retransform 不会把它去掉。

处理顺序

基线 → 此前经过的“不可重转换”transformer 的输出(直接沿用,不重新执行)→ 各“可重转换”transformer 依次重新处理 → 安装结果。

特点

  • 可撤销:每次都从基线出发,移除 transformer 后再 retransform 就能回到基线。
  • transformer 应当对同一份输入每次产生同样的结果,不要依赖“类已经被改过”。
  • 限制与 redefineClasses 相同:只能改方法体,不能增删成员;隐藏类不可修改。

参见:redefineClasses、Instrumentation、InstrumentationImpl

你对本条的回应 · 登录后可表态

讨论(0)

讨论不进入条目正文的版本历史,适合提出修改建议、指出问题或补充来源。
还没有人讨论这个条目。你可以提出修改建议、指出问题或补充来源。

发表话题

请先 登录 后再参与讨论。