Mmc秒杀圈百科 

redefineClasses

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

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

redefineClasses(Instrumentation.redefineClasses(ClassDefinition...))直接用调用者给出的字节码替换已加载类的定义,不参考类原有的字节码。底层对应 JVMTI 的 RedefineClasses,也就是调试器“热替换”用的机制。

用法

  • agent 清单声明 Can-Redefine-Classes: true,可用 isRedefineClassesSupported() 检查。
  • 参数是 ClassDefinition(Class, byte[]),可一次传多个类,要么全部成功,要么全部失败。
  • 传入的字节码同样会经过已注册的 transformer(见 Instrumentation)。

限制

  • 只能改方法体、常量池等,不能增删或改名字段与方法,不能改访问修饰符、父类和接口(HotSpot 默认不支持,会抛 UnsupportedOperationException)。
  • 类名必须一致,字节码要通过校验。
  • 不会重新执行静态初始化器,已有实例的字段值不变;正在执行的旧方法栈帧继续跑旧代码,新调用才使用新代码。
  • 基本类型、数组类和隐藏类不可修改,isModifiableClass 返回 false。

与 retransformClasses 的区别

  • 起点不同:redefine 完全以传入的字节为准;retransformClasses 从“基线”字节出发,再让 transformer 重新处理。
  • 会改变基线:redefine 成功后,类的基线被换成这次传入的字节,之后的 retransform 以它为起点。
  • 不可撤销:redefine 之后原来的字节码不会自动保留,要还原只能自己保存原字节再 redefine 一次;retransform 则可以靠移除 transformer 后重新 retransform 回到基线。

参见:retransformClasses、JavaAgent、Mixin

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

讨论(0)

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

发表话题

请先 登录 后再参与讨论。