gpt4 book ai didi

java - 堆叠 ASM 访问者的正确方法是什么?

转载 作者:行者123 更新时间:2023-12-01 14:16:56 28 4
gpt4 key购买 nike

我有以下代码:

for (Map.Entry<String, ClassReader> e : classes.entrySet())
{
ClassReader reader = e.getValue();
ClassWriter writer = new ClassWriter(Opcodes.ASM7);

// Process all visitors
reader.accept(new StringRemapper(writer, "String A", "String A!!"), ClassReader.EXPAND_FRAMES);
reader.accept(new StringRemapper(writer, "String B", "String B!!"), ClassReader.EXPAND_FRAMES);

// Update the class
reader = new ClassReader(writer.toByteArray());
e.setValue(reader);
}

上面代码的问题是它把所有的东西都写了两次,因为有两个访问者写给同一个作者(我猜)。

要解决这个问题,我需要在每个 reader.accept 之后添加下面的代码:

reader = new ClassReader(writer.toByteArray());
writer = new ClassWriter(Opcodes.ASM7);

问题是,这样做是不是在滥用访问者模式?我的意思是,为什么我需要创建一个新的读取器/写入器并且只访问一次?我不应该有多个访客吗?

我发现了这个类似的问题 Easy way to stack up a couple of ASM-Bytecode visitors?但无法理解接受的答案。

我尝试将第一个访问者作为参数传递给第二个而不是原始的 ClassWriter,结果相同,代码重复。

ClassVisitor last;
// Process all visitors
reader.accept(last = new StringRemapper(writer, "String A", "String A!!"), ClassReader.EXPAND_FRAMES);
reader.accept(new StringRemapper(last, "String B", "String B!!"), ClassReader.EXPAND_FRAMES);

最佳答案

你是对的,你确实错过了一些东西:ClassWriter 本身就是一个 ClassVisitor

堆叠访问者的正确方法是将其父访问者传递给构造函数:

// The root visitor is the ClassWriter
ClassVisitor cv = writer;

// Add a visitor
cv = new StringRemapper(cv, "String A", "String A!!");
// Add another one
cv = new StringRemapper(cv, "String B", "String B!!");
// maybe add more?

// Process them
reader.accept(cv, ClassReader.EXPAND_FRAMES);
byte[] classFile = writer.toByteArray();

如果您的 StringRemapper 只接受一个 ClassWriter 作为参数,那么您应该将其更改为接受 ClassVisitor 的 instread。

我注意到的另一件事是您的 classes 变量:它包含 ClassReader 作为值。
使用 ClassVisitors 作为值可能是一种更简单的设计 - 具有初始 ClassWriter 值。
但这是一个更大的设计变更。

关于java - 堆叠 ASM 访问者的正确方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62111615/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com