创建接口我们使用DummyInterface类来创建。首先创建一个DummyInterface对象,可以通过一下几种方式
1. DummyInterface dummy = new DummyInterface(); 2. DummyInterface dummy = new DummyInterface("asmsupport.test.Test"); 3. DummyInterface dummy = new DummyInterface("asmsupport.test", "Test");
上面三种方式,第一种仅仅知识啊创建一个DummyInterface对象,第二种方式在创建对象的同时赋予的接口的全限定名。第三种方式将包名和类名分开指定。
如果在构造DummyInterface的同时已经赋予了包名和类名,那么这里就可以不用为其设置。当然也可以在这里重新设置,将以前的值覆盖。
dummy.package_("asmsupport.test").name("Test")
接口的访问控制权限有public和默认(default)值。默认情况先创建的DummyInterface是default的访问权限,可以通过一下方式设置或者充值访问权限
dummy.public_() : 设置成public dummy.default_() : 设置成默认
在接口里面创建的field是都是默认具有public static final修饰的。通过下面代码创建field
DummyField field = dummy.newField(String.class, "FIELD");
上面的代码为接口创建了FIELD的field。等同于“public static final String FIELD”,如果仅仅值调用了上面的代码,那么FIELD的值就是null。有两种方式为.
这里将介绍如何创建接口的方法。通过DummyInterface的newMethod方法创
DummyInterfaceMethod method = dummy.newMethod("test");
通过上面的代码就已经告诉asmsupport了,创建一个test的方法,但是test方法仅仅是如下内容
public void test();
由于是接口方法,所以public的修饰符是无法改变的,但是方法的返回类型已经参数列表是可以改变了。
在编写java代码的时候,接口内是不允许有static程序块的,但是使用asmsupport有这样的特权。通过下面的方式
dummy.newStaticBlock(new StaticBlockBody() { @Override public void body(){ GlobalVariable FIELD = getMethodOwner().field("FIELD"); assign(FIELD, call(String.class, "valueOf", val(100))); GlobalVariable out = defType(System.class).field("out"); call(out, "println", val("Hello ASMSupport")) return_(); } });
在这里我们创建出了一个静态程序块,在程序块中为我们在上面创建的FIELD赋值,同时还打印了“Hello ASMSupport”,这个在java中是无法实现的。最后我们显式的调用了return。
我们会根据当前使用的JDK版本自动选择class的版本,但是也可以显式的设置class版本,通过下面的方式
dummy.setJavaVersion(Opcodes.V1_5)
我们内置ClassLoader来完成我们生成的class的字节数组到class对象,当然也允许自定义classloader通过下面的方法
dummy.setClassLoader(classloader);
dummy.setClassOutPutPath("../classes");
设置这个属性,我们生成的class将会输出到指定目录,这样我们可以通过反编译大致看下class内容是否和预期相同。
Class<?> clazz = dummy.build();
到这里我们就完成了一个接口的创建。生产的代码大致如下:
package asmsupport.test public interface Test extends List, Cloneable{ public String FIELD = String.valueOf(100); static { System.out.println("Hello ASMSupport"); } public String test(int arg1, double arg2) throws RuntimeException, IOException; }