生成类
生成一个无任何成员方法,变量,无继承,无实现的类。
/** * 生成一个无任何成员方法,变量,无继承,无实现的类。 */ public void testCreateBlankClass(){ ClassCreator creator = new ClassCreator(Opcodes.V1_5, Opcodes.ACC_PUBLIC, "generated.create.CreateBlankClass", null, null); creator.setClassOutPutPath(".//target//"); creator.startup(); } |
生成一个有成员变量的类
/** * 生成一个成员变量的类。 */ public void testCreateMemberVarClass(){ ClassCreator creator = new ClassCreator(Opcodes.V1_5, Opcodes.ACC_PUBLIC, "generated.create.CreateMemberVarClass", null, null); creator.createGlobalVariable("globalVar1", Opcodes.ACC_PUBLIC, AClass.STRING_ACLASS); creator.createGlobalVariable("globalVar2", Opcodes.ACC_PRIVATE, AClass.STRING_ACLASS); creator.createGlobalVariable("globalVar3", Opcodes.ACC_PROTECTED, AClass.STRING_ACLASS); creator.createGlobalVariable("globalVar4", Opcodes.ACC_STATIC, AClass.STRING_ACLASS); creator.createGlobalVariable("globalVar5", Opcodes.ACC_PUBLIC + Opcodes.ACC_STATIC, AClass.INT_ACLASS); creator.setClassOutPutPath(".//target//"); creator.startup(); } |
变量的可见性可以进行叠加,例如globalVar5,公开的静态成员
生成一个有成员变量的类,同时对变量进行初始化
/** * 生成一个成员变量的类。同时对成员变量和静态成员变量进行初始化 */ public void testCreateMemberVarInitClass(){ ClassCreator creator = new ClassCreator(Opcodes.V1_5, Opcodes.ACC_PUBLIC, "generated.create.CreateMemberVarInitClass", null, null); creator.createGlobalVariable("globalVar1", Opcodes.ACC_PUBLIC, AClass.STRING_ACLASS); creator.createGlobalVariable("globalVar2", Opcodes.ACC_PRIVATE, AClass.STRING_ACLASS); creator.createGlobalVariable("globalVar3", Opcodes.ACC_PROTECTED, AClass.STRING_ACLASS); creator.createGlobalVariable("globalVar4", Opcodes.ACC_STATIC, AClass.STRING_ACLASS); creator.createGlobalVariable("globalVar5", Opcodes.ACC_PUBLIC + Opcodes.ACC_STATIC, AClass.STRING_ACLASS); creator.createConstructor(new AClass[0], new String[0], new InitBody() {
@Override public void body(LocalVariable... argus) { invokeSuperConstructor(); assign(getThis().getGlobalVariable("globalVar1"), Value.value("this is globalVar1 init")); assign(getThis().getGlobalVariable("globalVar2"), Value.value("this is globalVar2 init")); assign(getThis().getGlobalVariable("globalVar3"), Value.value("this is globalVar3 init")); runReturn(); } }, Opcodes.ACC_PUBLIC); creator.createStaticBlock(new ClinitBody() { @Override public void body() { assign(getMethodOwner().getGlobalVariable("globalVar4"), Value.value("this is globalVar4 init")); assign(getMethodOwner().getGlobalVariable("globalVar5"), Value.value("this is globalVar5 init")); runReturn(); } }); creator.setClassOutPutPath(".//target//"); creator.startup(); } |
assign()方法可用于静态成员、实例成员进行绑定。
静态代码块和接口中用的静态代码块一致。
createConstructor创建构造函数,第一个参数描述输入参数类型,第二个参数描述输入参数名称,第三个参数为InitBody对象。
InitBody对象类似于CinitBody,都拥有形式一样的body(LocalVariable... argus)方法,方法体结束也需要调用runReturn。
在类中或者方法中获取类实例可以使用getThis()方法获取this对象。由于我们创建的globalVariable是非static的。所以通过getThis()获取globalVariable。getThis()对应于java代码中就是this关键字。
createConstructor方法有四个参数依次是:
1. 构造方法的所有参数类型的数组
2. 构造方法所有参数的名称
3. 构造参数的方法体
4. 构造方法的修饰符
这个方法中的内容就是我们创建的构造方法里面需要执行的内容了,他有一个变元参数 argus。这里的参数表示的是我们当前创建的构造方法的参数。这个数组中每个LocalVariable和createConstructor方法的第一个参数中的AClass数组一一对应的。
要显示的调用invokeSuperConstructor,他的作用就是等同于我们编写java代码的时候调用super()一样。只不过我们在用java创建个构造函数的时候有时候不需要调用super,是应为父类的存在没有参数的构造方法。但这并不代码jvm没有去调用super().其实编译器在编译java的时候已经将调用super的指令加上到了构造方法的字节码中去了。这个方法存在一个变元参数arguments。他表示我们调用super()的时候需要传递的参数,由于我们创建的class没有继承任何类即只继承了Object类,那么我们就不需要传递参数直接调用invokeSuperConstructor();
生成一个有成员变量的类,同时使用构造器对变量初始化
/** * 生成一个有成员变量的类,同时使用构造器对变量初始化 */ @Test public void testCreateMemberVarInit2Class(){ ClassCreator creator = new ClassCreator(Opcodes.V1_5, Opcodes.ACC_PUBLIC, "generated.create.CreateMemberVarInit2Class", null, null); creator.createGlobalVariable("globalVar1", Opcodes.ACC_PRIVATE, AClass.STRING_ACLASS); creator.createGlobalVariable("globalVar2", Opcodes.ACC_PUBLIC + Opcodes.ACC_STATIC, AClass.STRING_ACLASS); creator.createConstructor(new AClass[]{AClass.STRING_ACLASS, AClass.STRING_ACLASS}, new String[]{"init1", "init2"}, new InitBody() {
@Override public void body(LocalVariable... argus) { invokeSuperConstructor(); assign(getThis().getGlobalVariable("globalVar1"), argus[0]); assign(getMethodOwner().getGlobalVariable("globalVar2"), argus[1]); runReturn(); } }, Opcodes.ACC_PUBLIC); creator.setClassOutPutPath(".//target//"); creator.startup(); } |
生成一个类,创建一个成员方法
/** * 生成一个类,创建一个成员方法 */ @Test public void testCreateMemberMethod1Class(){ ClassCreator creator = new ClassCreator(Opcodes.V1_5, Opcodes.ACC_PUBLIC, "generated.create.CreateMemberMethod1Class", null, null); creator.createMethod("method0", new AClass[]{}, new String[]{}, AClass.VOID_ACLASS, null, Opcodes.ACC_PUBLIC, new CommonMethodBody() {
@Override public void body(LocalVariable... argus) {
} }); creator.setClassOutPutPath(".//target//"); creator.startup(); } |
成员方法与构造方法类似,唯一不同是最后一个方法体。CommonMethodBody是成员方法的实现逻辑抽象。Argus中的顺序与第2、3参数的顺序一致。
生成一个类,创建一个成员方法,有字符串类型输入,有字符串类型返回,同时将输入的参数输出到标准输出,然后返回该参数
/** * 生成一个类,创建一个成员方法,有字符串类型输入,有字符串类型返回,同时将输入的参数输出到标准输出,然后返回该参数 */ @Test public void testCreateMemberMethod2Class(){ ClassCreator creator = new ClassCreator(Opcodes.V1_5, Opcodes.ACC_PUBLIC, "generated.create.CreateMemberMethod2Class", null, null); creator.createMethod("method0", new AClass[]{AClass.STRING_ACLASS}, new String[]{"input_param"}, AClass.STRING_ACLASS, null, Opcodes.ACC_PUBLIC, new CommonMethodBody() {
@Override public void body(LocalVariable... argus) { GlobalVariable systemOut = AClassFactory.getProductClass(System.class).getGlobalVariable("out"); invoke(systemOut, "println", argus[0]); runReturn(argus[0]); } }); creator.setClassOutPutPath(".//target//"); creator.startup(); }
|
使用非生成的的类成员变量,可使用如下方式实现。
1.获取已有类的AClass封装,使用AClassFactory.getProductClass(Class)获取
2.调用AClass对象的获取全局变量方法,getGlobalVariable(String),获取对应名称的静态成员变量。
执行一个变量的一个成员方法,可使用如下方式实现
1.获取变量对应的Parameterized封装
2.调用invoke方法,第一个参数为包括该方法的对象Parameterized封装,第二个参数为执行的方法名,第三个参数为参数对应的输入,是一个Parameterized数组。对于重载函数,会根据这个参数自动匹配。
生成一个内部类
目前框架不支持
生成一个内部接口
目前框架不支持
生成一个内部枚举
目前框架不支持
生成一个类,实现一个接口
/** * 生成一个类,实现一个接口 */ @Test public void testCreateImplementInterface(){ ClassCreator creator = new ClassCreator(Opcodes.V1_5, Opcodes.ACC_PUBLIC, "generated.create.CreateImplementInterface", null, new Class[]{FileFilter.class}); creator.createMethod("accept", new AClass[]{AClassFactory.getProductClass(File.class)}, new String[]{"file"}, AClass.BOOLEAN_ACLASS, null, Opcodes.ACC_PUBLIC, new CommonMethodBody() {
@Override public void body(LocalVariable... argus) { GlobalVariable sysout = AClassFactory.getProductClass(System.class).getGlobalVariable("out"); invoke(sysout, "println", argus[0]); runReturn(Value.value(false)); } }); creator.setClassOutPutPath(".//target//"); creator.startup(); } |
生成一个类,继承一个类,父类有一个无参构造
/** * 生成一个类,继承一个接口,父类有一个无参构造函数 */ @Test public void testCreateExtendsParentClassNone(){ ClassCreator creator = new ClassCreator(Opcodes.V1_5, Opcodes.ACC_PUBLIC, "generated.create.CreateExtendsParentClassNone", ParentClass.class, null); creator.createConstructor(new AClass[]{}, new String[]{}, new InitBody() { @Override public void body(LocalVariable... argus) { invokeSuperConstructor(); GlobalVariable sysout = AClassFactory.getProductClass(System.class).getGlobalVariable("out"); invoke(sysout, "println", Value.value("这是一个无参构造")); runReturn(); } }, Opcodes.ACC_PUBLIC); creator.createMethod("method1", new AClass[]{AClass.INT_ACLASS}, new String[]{"i"}, AClass.STRING_ACLASS, new AClass[]{AClassFactory.getProductClass(IOException.class)}, Opcodes.ACC_PUBLIC, new CommonMethodBody() {
@Override public void body(LocalVariable... argus) { GlobalVariable sysout = AClassFactory.getProductClass(System.class).getGlobalVariable("out"); invoke(sysout, "println", argus[0]); runReturn(Value.value("this is a extend demo")); } }); creator.setClassOutPutPath(".//target//"); creator.startup(); } |
生成一个类,继承一个类,父类有一个有参构造
/** * 生成一个类,继承一个接口,父类有一个无参构造函数 */ @Test public void testCreateExtendsParentClassExist(){ ClassCreator creator = new ClassCreator(Opcodes.V1_5, Opcodes.ACC_PUBLIC, "generated.create.CreateExtendsParentClassExist", ParentClassA.class, null); creator.createConstructor(new AClass[]{AClass.STRING_ACLASS}, new String[]{"msg"}, new InitBody() { @Override public void body(LocalVariable... argus) { invokeSuperConstructor(argus); GlobalVariable sysout = AClassFactory.getProductClass(System.class).getGlobalVariable("out"); invoke(sysout, "println", Value.value("这是一个有参构造")); invoke(sysout, "println", argus[0]); runReturn(); } }, Opcodes.ACC_PUBLIC); creator.createMethod("method1", new AClass[]{AClass.INT_ACLASS}, new String[]{"i"}, AClass.STRING_ACLASS, new AClass[]{AClassFactory.getProductClass(IOException.class)}, Opcodes.ACC_PUBLIC, new CommonMethodBody() {
@Override public void body(LocalVariable... argus) { GlobalVariable sysout = AClassFactory.getProductClass(System.class).getGlobalVariable("out"); invoke(sysout, "println", argus[0]); runReturn(Value.value("this is a extend demo")); } }); creator.setClassOutPutPath(".//target//"); creator.startup(); } |