2.2.4 类的转换
之前的例子中ClassReader和ClassWriter这两个组件都是分开用的,现在这里给出一个两个组件联合使用的例子。
第一步,将ClassReader产生的事件定向到ClassWriter中,让ClassWriter重构由ClassReader读取出来的类:
byte[] bs1 = ...
ClassWriter classWriter = new ClassWriter();
ClassReader classReader = new ClassReader(bs1);
classReader.accept(classWriter, 0);
byte[] bs2 = classWriter.toByteArray();
上面的代码只是复制了一遍byte数组,所以第二步要在ClassReader和ClassWriter之间设置一个ClassAdapter,这里设置一个默认的ClassAdapter:
byte[] bs1 = ...
ClassWriter classWriter = new ClassWriter();
ClassAdapter classAdapter = new ClassAdapter(classWriter);
ClassReader classReader = new ClassReader(bs1);
classReader.accept(classAdapter, 0);
byte[] bs2 = classWriter.toByteArray();
事件 事件
ClassReader -----------------> ClassAdapter -----------------> ClassWriter
上面的例子中使用了一个默认的ClassAdapter,默认的ClassAdapter是什么处理也没有做的,所以输出的byte数组和输入的byte数组内容是相同的。
所以,要想通过使用ASM来真正修改一个类的字节码,必须扩展ClassAdapter,覆盖其中的某些方法:
下面举1个例子,这个例子是修改一个类的字节码中的Java版本信息(统一改成Java1.5):
public class ModifyJavaVersionAdapter extends ClassAdapter {
public ModifyVersionAdapter(ClassVisitor classVisitor) {
super(classVisitor);
}
public void visit(int version, int modifiers, String name, String signature, String parentName, String[] interfaces) {
super.visit(Opcodes.V1_5, modifiers, name, signature, parentName, interfaces);
}
}