该
LocalVariableSorter班有一个设计,这使得它非常容易出错使用它。
当调用由
MethodVisitorAPI
定义的方法时,它们将进行类文档中提到的重新编号。
因此,当与一起使用时
ClassReader,所访问的旧代码将被转换。由于您不希望注入的新代码进行此转换,而是使用新定义的变量,因此必须绕过
LocalVariableSorter基础target上的and调用方法
MethodVisitor。
当你打电话
visitVarInsn(LSTORE,3)的
LocalVariableSorter,它就会像一个老指令引用索引处理
3因为你注入了新的变量占用的索引
3和
4索引,“老变量”
3被重新映射到一个空闲的索引,这是
5(和
6)。然后,当你定义你的下一个新的变量,它得到指数
7,并呼吁
visitVarInsn(ASTORE,7)在
LocalVariableSorter是像一个老变量处理与您的新的变量冲突,因此它被重新映射到
8。
此行为与类文档的第一句话完全匹配:
LocalVariablesSorter
一个MethodVisitor,它按出现顺序对局部变量重新编号。
所以,当你要调用
newLocal的
LocalVariableSorter创建将不会被重新映射一个新的变量,你必须调用
visit…原始方法,包
MethodVisitor使用它。使用子类时
GeneratorAdapter,可以使用其新定义的方法(不是以开头的方法
visit…)来创建不会被转换的新指令,但是对我来说,如果拥有用于转换指令和创建未转换指令的方法,情况将变得更糟。在同一个类上,并且始终需要记住
visit…前缀会有所不同。对于某些方法,您仍然需要访问原始方法访问者,如本答案中所讨论的,该访问者处理
visitLocalVariable为创建的变量创建调试信息。



