我使用ASM,这非常简单。我有一个org.objectweb.asm.commons.Remapper的实现,它将类的名称和描述符更改为新类。
例如其中一种方法是这样的:
@Override
public String mapDesc(String desc) {
return super.mapDesc(StringUtil.fixDesc(desc, renamed));
}
的描述如下所示:LCOM /示例/类;。我将这个字段'重命名为',我将其添加到fixDesc中,这是一个包含旧值到新值的类映射的映射。所以,如果我想使COM /例子/ AAA到COM /例子/ BBB我喂之前和之后的值到地图,并调用重映射器,像这样:
/**
* Given a map of ClassNodes and mappings, returns a map of class names to
* class bytes.
*/
public static Map<String, byte[]> process(Map<String, ClassNode> nodes, Map<String, MappedClass> mappings) {
Map<String, byte[]> out = new HashMap<String, byte[]>();
RemapperImpl mapper = new RemapperImpl(mappings);
for (ClassNode cn : nodes.values()) {
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
ClassVisitor remapper = new ClassRemapper(cw, mapper);
cn.accept(remapper);
out.put(mappings.get(cn.name).getNewName(), cw.toByteArray());
}
return out;
}
为什么会有人想修改一个编译的类? –
@Vishal Kamat,如果你想不出为什么,那就意味着你不需要。在某些情况下它可能很有用,例如,添加一个额外的方法并在没有源代码的类上实现一个接口。在我的情况只是一个沙箱测试。 –
在这种情况下,AOP是你的朋友。很多东西在做它只是你提到的 –