一、ASM版本:
我们常用的java版本是java8和java11,针对java 8我们需要使用ASM5.0版本,对于java11我们需要使用ASM7.0版本。当然我们可以尽量使用较高的ASM版本

二、ASM能做什么
•程序分析,范围从简单的语法分析到完整的语义分析,可用于发现应用程序中的潜在错误,
检测未使用的代码,对代码进行反向工程等。
•在编译器中使用程序生成。这包括传统编译器,但也包括用于分布式编程的存根或框架编译器、
即时编译器等。
•程序转换可用于优化或混淆程序,要在应用程序中插入调试或性能监视代码,用于面向方面编程等。

三、ASM的两个组成部分
从组成结构上来说,ASM分成两部分,Core API Tree API
- 其中,Core API包括asm.jar,asm-util.jar和asm-commons.jar
- 其中,Tree API包括asm-tree.jar和asm-analysis.jar
四、使用ASM
4.1. 预期目标
我们的预期目标是,生成一个HelloWorld类,它对应的Java代码如下:
package sample;
public class HelloWorld {
@Override
public String toString() {
return "This is a HelloWorld object.";
}
}
注意,我们不需要去写这样一个sample/HelloWorld.java文件,只是生成的HelloWorld类和这里的Java代码是一样的效果。
4.2. 编码实现
package com.example;
import org.objectweb.asm.*;
public class HelloWorldDump implements Opcodes {
public static byte[] dump() {
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
cw.visit(V1_8, ACC_PUBLIC | ACC_SUPER, "sample/HelloWorld", null, "java/lang/Object", null);
{
MethodVisitor mv1 = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
mv1.visitCode();
mv1.visitVarInsn(ALOAD, 0);
mv1.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false);
mv1.visitInsn(RETURN);
mv1.visitMaxs(1, 1);
mv1.visitEnd();
}
{
MethodVisitor mv2 = cw.visitMethod(ACC_PUBLIC, "toString", "()Ljava/lang/String;", null, null);
mv2.visitCode();
mv2.visitLdcInsn("This is a HelloWorld object.");
mv2.visitInsn(ARETURN);
mv2.visitMaxs(1, 1);
mv2.visitEnd();
}
cw.visitEnd();
return cw.toByteArray();
}
}
4.3. 验证结果
package com.example;
public class MyClassLoader extends ClassLoader {
@Override
protected Class<?> findClass(String name) throws ClassNotFoundException {
if ("sample.HelloWorld".equals(name)) {
byte[] bytes = HelloWorldDump.dump();
Class<?> clazz = defineClass(name, bytes, 0, bytes.length);
return clazz;
}
throw new ClassNotFoundException("Class Not Found: " + name);
}
}
package com.example;
public class HelloWorldRun {
public static void main(String[] args) throws Exception {
MyClassLoader classLoader = new MyClassLoader();
Class<?> clazz = classLoader.loadClass("sample.HelloWorld");
Object instance = clazz.newInstance();
System.out.println(instance);
}
}
运行之后的输出结果:
This is a HelloWorld object.
网友评论