java - 如何复制 InsnList
问题描述
InsnList 没有复制自身的方法。
我试图迭代列表并将每个节点添加到新列表中。但是迭代列表的副本执行 npe
private static InsnList copy(InsnList insnList) {
InsnList r = new InsnList();
for (int i = 0; i < insnList.size(); i++)
r.add(insnList.get(i));
return r;
}
InsnList copy = copy(someList);
for (int i = 0; i < copy.size(); i++)
System.out.println(copy.get(i));
我预计副本会,但副本的迭代会产生跟随错误
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 1
at org.objectweb.asm.tree.InsnList.toArray(InsnList.java:199)
at org.objectweb.asm.tree.InsnList.get(InsnList.java:110)
解决方案
虽然我无法重现您的特定异常,但这似乎只是您的方法存在根本问题的另一个症状。作为国家的文件AbstractInsnNode
:
表示字节码指令的节点。一条指令一次最多只能出现
InsnList
一次。
所以你不能复制一个InsnList
,至少不能通过将相同的节点插入另一个列表。这也是从源列表中删除节点的add(InsnList)
和insert(InsnList)
方法的原因。InsnList
当您真正想要 的副本时InsnList
,您还必须创建节点对象的副本,这通过访问者 API 最容易完成:
private static InsnList copy(InsnList insnList) {
MethodNode mv = new MethodNode();
insnList.accept(mv);
return mv.instructions;
}
但只要任务允许,您应该使用 ASM 的访问者 API 将指令直接写入目标类文件,而不是创建指令列表的副本。另请参阅有关您的实际任务的答案。
推荐阅读
- django - 如何为随机网址创建视图?
- javascript - 为什么 Rxjs 在订阅回调中出错时取消订阅?
- ruby - 使用 Ruby 和 Bing Ads API v2.0 的任何示例?
- docker - 如何在docker中分配时区
- html - IE上的背景位置
- c# - Azure 函数 blob BlobPath 转为小写
- c++ - 如何在qt c++中使用QPainter在stackedwidget页面上绘制不同的几何图形,如圆形?
- html - 响应式 css 网格图像库
- reactjs - converter.json2csv(header) - 测试
- android - 如何在 Android 中收听所有传出的短信(API 20 到 28)