【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>>
这里不做过多解释,先通过下面的代码生成一个class,再通过反射调用其main方法,感受下ASMSupport的奇妙
1.首先创建一个抽象类
public abstract class AbstractExample {
/**
* system.out global variable
*/
public static GlobalVariable systemOut = AClassFactory.getProductClass(System.class).getGlobalVariable("out");
public static Class<?> generate(IClassContext creator){
//_这是Class的输出路径。主要为了调试作用。我们通过asmsupport生成的class将获输出到这个路径
//你可以通过反编译软件看看我们生成的结果
creator.setClassOutPutPath(".//target//");
//这个就是个开关。前面我们把该创建的方法变量都放到了传送带上了。调用startup
//启动传送带,将上面的东西一个个处理给我返回一个我们需要的成品(就是class了)
Class<?> cls = creator.startup();
//如果创建的是非枚举类型或者非接口类型则调用main方法
if(creator instanceof ClassCreator){
try {
cls.getMethod("main", String[].class).invoke(cls, new Object[]{null});
} catch (Exception e) {
e.printStackTrace();
}
}
return cls;
}
}
2.接下来就是asmsupport生成class的代码了
public class HelloWorld extends AbstractExample{
/**
* @throws NoSuchMethodException
* @throws SecurityException
* @throws InvocationTargetException
* @throws IllegalAccessException
* @throws IllegalArgumentException
*/
public static void main(String[] args) {
ClassCreator creator = new ClassCreator(Opcodes.V1_5, Opcodes.ACC_PUBLIC , "generated.helloworld.HelloWorldExample", null, null);
creator.createStaticMethod("main", new AClass[]{AClassFactory.getProductClass(String[].class)}, new String[]{"args"}, null, null,
Opcodes.ACC_PUBLIC + Opcodes.ACC_STATIC, new StaticMethodBody(){
@Override
public void generateBody(LocalVariable... argus) {
invoke(systemOut, "println", Value.value("Hello World"));
//don't forget return.
runReturn();
}
});
generate(creator);
}
}
3.OK 直接run这个HelloWorld类,在打印的最下面一行出现了我们熟悉的“Hello World”
文章地址:http://my.oschina.net/wensiqun/blog/116067
ASM源码地址:https://amssupport.googlecode.com/svn/trunk/ 文章实例地址:http://amssupport.googlecode.com/svn/trunk/asmsupport/src/test/java/example/helloworld/ 以上代码均可通过svn下载
来源:oschina
链接:https://my.oschina.net/u/238125/blog/116067