ASMSupport教程4.3赋值操作

4.3 生成复制操作

这一节将讲述如何生成,我们预计上生成如下代码:

public class AssignmentGenerateExample

{
public static String commonMethod()
{

return "I'm from commonMethod";

}

public static void main(String[] args)
{

String string = null;
string = commonMethod();
System.out.println("first asign :" + string);
string = "second assing value";
System.out.println("second asign :" + string);

}
}

这段代码然我们看到了为变量赋值null,将方法返回值复制给变量,以及将常量复制给null。那么对应的ASMSupport的代码如下:

public static void main(String[] args) {
    ClassCreator creator = new ClassCreator(Opcodes.V1_5, Opcodes.ACC_PUBLIC , "generated.operators.AssignmentGenerateExample", null, null);

    creator.createStaticMethod("commonMethod", null, null, AClass.STRING_ACLASS, null, Opcodes.ACC_PUBLIC, new StaticMethodBody(){

        @Override
        public void generateBody(LocalVariable... argus) {
            runReturn(Value.value("I'm from commonMethod"));
        }
    });

    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) {
            //position 1创建个String变量默认赋值为null
            LocalVariable string = createVariable("string", AClass.STRING_ACLASS, false, null);
            //position 2
            assign(string, invokeStatic(getMethodOwner(), "commonMethod"));
            invoke(systemOut, "println", append(Value.value("first asign :"), string));
            //position 3
            assign(string, Value.value("second assing value"));
            invoke(systemOut, "println", append(Value.value("second asign :"), string));

            runReturn();
        }
    });
    generate(creator);
}

上面的代码中systemOut是AClassFactory.getProductClass(System.class).getGlobalVariable("out")的返回值。

上面的的代码中,position 1下面的一行就是创建名为string的变量,类型是String类型,并且将null赋值给变量,下面我们将解释下这行代码。

createVariable("string", AClass.STRING_ACLASS, false, null)

  • 第一参数是变量名;
  • 第二个参数是变量类型, 其类型是AClass的类型(参见ASMSupport教程1之动态生成接口了解更多关于AClass第一段)
  • 第三个参数表示当前创建的变量名是否是匿名的,如果是ture,表示此变量为匿名变量即第一个参数设置的变量名无效
  • 第四个参数表示创建变量的时候赋予的默认值,这里是null,当然如果我们调用方法,并将返回值赋值给变量,我们这里也可以直接只用position 2下面的代码中的invokeStatic(getMethodOwner(), "commonMethod")放在这里

在上面我们讲了如何在创建变量的同时赋值,接下来是我们将值赋予给已经存在的变量,这个操作需要的就是assign方法, 我们可以看到position 2下的代码如下:

assign(string, invokeStatic(getMethodOwner(), "commonMethod"))

  • 第一个参数,我们需要赋值的变量,这里可以是局部变量,也可以是全局变量(关于ASMSupport中如何创建局部变量和全局变量可参考ASMSupport教程2动态生成类)
  • 第二个参数,这个参数就是表示我们需要传递个变量的值,可以是null,可以是方法调用,可以是另一个变量,也可以是常量,只要是Parameterized类型的就可以,当然,这些值都必须和变量的类型相同或者是其子类,这和java代码是一样的。

在position 3下的代码和position 2的大致相同只不过这里直接使用Value.value("second assing value")定义常量,而上面的是一个方法调用操作。

 

本系列教程所有实例代码在下载页面最下面,有两种下载方式,推荐第二个,而第一个是trunk上的代码,第二个是对于0.2版本的, 最近空间可能有点不稳定,多刷新下吧

你可能感兴趣的:(ASMSupport教程4.3赋值操作)