ASMSupport教程4.4 自增减操作(++,

Stella981
• 阅读 268

4.4 自增减操作(++,—)

我们知道,++和--是各种编程语言的基本操作,其作用就不解释了,直接进入正题,我们希望生成如下代码

package generated.operators;

import java.io.PrintStream;

public class CrementOperatorGenerateExample { public void demonstrate() { System.out.println("***demonstrate"); int a = 1; int b = 2; b++; int c = b; int d = a; a++; c++; System.out.println("a = " + a); System.out.println("b = " + b); System.out.println("c = " + c); System.out.println("d = " + d); }

public void incrementAndDecrement() { System.out.println("***incrementAndDecrement"); int count = 10; count++; count--; System.out.println("count = " + count); }

public static void main(String[] args) { CrementOperatorGenerateExample currentObj = new CrementOperatorGenerateExample(); currentObj.demonstrate(); currentObj.incrementAndDecrement(); } }

那么通过如下ASMSupport代码就能生成:

package example.operators;

import org.objectweb.asm.Opcodes;

import jw.asmsupport.block.method.common.CommonMethodBody; import jw.asmsupport.block.method.common.StaticMethodBody; import jw.asmsupport.clazz.AClass; import jw.asmsupport.clazz.AClassFactory; import jw.asmsupport.creator.ClassCreator; import jw.asmsupport.definition.value.Value; import jw.asmsupport.definition.variable.LocalVariable;

import example.AbstractExample;

public class CrementOperatorGenerate extends AbstractExample {

/**
 * @param args
 */
public static void main(String[] args) {

    ClassCreator creator = new ClassCreator(Opcodes.V1_5, Opcodes.ACC_PUBLIC , "generated.operators.CrementOperatorGenerateExample", null, null);
    
    /*
     * 对应java代码
     * public void demonstrate() {
     *     System.out.println("******************************demonstrate***************************");
     *     int a = 1;
     *     int b = 2;
     *     int c;
     *     int d;
     *     c = ++b;
     *     d = a++;
     *     c++;
     *     System.out.println("a = " + a);
     *     System.out.println("b = " + b);
     *     System.out.println("c = " + c);
     *     System.out.println("d = " + d);
     * }
     */
    creator.createMethod("demonstrate", null, null, null, null, Opcodes.ACC_PUBLIC, new CommonMethodBody() {
        @Override
        public void generateBody(LocalVariable... argus) {
            invoke(systemOut, "println", Value.value("******************************demonstrate***************************"));
            
            //int a = 1;
            LocalVariable a = createVariable("a", AClass.INT_ACLASS, false, Value.value(1));
            //int b = 2;
            LocalVariable b = createVariable("b", AClass.INT_ACLASS, false, Value.value(2));
            //int c = ++b;
            LocalVariable c = createVariable("c", AClass.INT_ACLASS, false, beforeInc(b));
            //d = a++;
            LocalVariable d = createVariable("d", AClass.INT_ACLASS, false, afterInc(a));
            //c++;
            afterInc(c);
            
            //System.out.println("a = " + a);
            invoke(systemOut, "println", append(Value.value("a = "), a)); 
            invoke(systemOut, "println", append(Value.value("b = "), b)); 
            invoke(systemOut, "println", append(Value.value("c = "), c)); 
            invoke(systemOut, "println", append(Value.value("d = "), d)); 
            runReturn();
        }
    });
    
    /*
     * java code:
     * public void incrementAndDecrement(String[] argv) {
     *    System.out.println("******************************incrementAndDecrement***************************");
     *    int count = 10;
     *    ++count;
     *    --count;
     *    System.out.println(count);
     * }
     */
    creator.createMethod("incrementAndDecrement", null, null, null, null, Opcodes.ACC_PUBLIC, new CommonMethodBody() {
        @Override
        public void generateBody(LocalVariable... argus) {
            invoke(systemOut, "println", Value.value("******************************incrementAndDecrement***************************"));
            //int count = 10;
            LocalVariable count = createVariable("count", AClass.INT_ACLASS, false, Value.value(10));
            // ++count
            beforeInc(count); 
            // --count;
            beforeDec(count); 
            // System.out.println("count = " +  count);
            invoke(systemOut, "println", append(Value.value("count = "), count));
            runReturn();
        }
    });
    
    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) {
            LocalVariable currentObj = createVariable("currentObj", getMethodOwner(), false, invokeConstructor(getMethodOwner()));
            invoke(currentObj, "demonstrate");
            invoke(currentObj, "incrementAndDecrement");
            runReturn();
        }
    });
    generate(creator);
}

}

我们主要关注的是creator.createMethod("demonstrate", null, null, null, null, Opcodes.ACC\_PUBLIC, new CommonMethodBody()这份部分内容以及creator.createMethod("incrementAndDecrement", null, null, null, null, Opcodes.ACC\_PUBLIC, new CommonMethodBody()部分,创建变量部分就不解释了,如果不知道的可以参数前一章ASMSupport教程2动态生成类,我们这里主要关注一下四个方法:

  • beforeInc: 这个方法相当于++a操作
  • afterInc:这个方法相当于a++操作
  • beforeDec:这个方法相当于--a操作
  • afterDec:这个方法相当于a--操作

以上四个方法都只有一个参数,参数类型是继承Crementable类型的,在ASMSupport中jw.asmsupport.definition.variable.GlobalVariable和jw.asmsupport.definition.variable.LocalVariable。也就是说我们定义的类属性和局部变量都是可以的,但是得注意,这些变量必须是可以执行++或--操作的,这也和平常java语法是一样的。

本系列教程所有实例下载地址:http://www.wensiqun.com/download/118/

点赞
收藏
评论区
推荐文章
刚刚好 刚刚好
2个月前
css问题
1、 在IOS中图片不显示(给图片加了圆角或者img没有父级) <div<img src""/</div div {width: 20px; height: 20px; borderradius: 20px; overflow: h
blmius blmius
1年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录 问题 用navicat导入数据时,报错: 原因这是因为当前的MySQL不支持datetime为0的情况。 解决修改sql\mode: sql\mode:SQL Mode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。 全局s
晴空闲云 晴空闲云
2个月前
css中box-sizing解放盒子实际宽高计算
我们知道传统的盒子模型,如果增加内边距padding和边框border,那么会撑大整个盒子,造成盒子的宽度不好计算,在实务中特别不方便。boxsizing可以设置盒模型的方式,可以很好的设置固定宽高的盒模型。 盒子宽高计算假如我们设置如下盒子:宽度和高度均为200px,那么这会这个盒子实际的宽高就都是200px。但是当我们设置这个盒子的边框和内间距的时候,那
艾木酱 艾木酱
1个月前
快速入门|使用MemFire Cloud构建React Native应用程序
> MemFire Cloud是一款提供云数据库,用户可以创建云数据库,并对数据库进行管理,还可以对数据库进行备份操作。它还提供后端即服务,用户可以在1分钟内新建一个应用,使用自动生成的API和SDK,访问云数据库、对象存储、用户认证与授权等功能,可专
Easter79 Easter79
1年前
Twitter的分布式自增ID算法snowflake (Java版)
概述 == 分布式系统中,有一些需要使用全局唯一ID的场景,这种时候为了防止ID冲突可以使用36位的UUID,但是UUID有一些缺点,首先他相对比较长,另外UUID一般是无序的。 有些时候我们希望能使用一种简单一些的ID,并且希望ID能够按照时间有序生成。 而twitter的snowflake解决了这种需求,最初Twitter把存储系统从MySQL迁移
Stella981 Stella981
1年前
ASMSupport教程4.5 在Class中生成算术运算符
<h2>ASMSupport教程4.5 在Class中生成算术运算符</h2> <p>这节我们开始介绍ASMSupport如何生成算数运算符(+-\*/%),依旧先看我们需要生成的java代码:</p> <div id="scid:9D7513F9-C04C-4721-824A-2B34F0212519:22b13b06-a0d6-4b8e-b7cd-768
Stella981 Stella981
1年前
ASMSupport教程4.9 生成三元运算符
<p>这节我们介绍如何用ASMSupport生成三元运算符(... ? ... : ... )运算符。我们预计生成如下代码:</p> <div id="scid:9D7513F9-C04C-4721-824A-2B34F0212519:935e30cc-3321-4e00-93ba-9834f3a4e044" class="wlWriterEditableS
Stella981 Stella981
1年前
ASMSupport教程4.12 生成方法调用操作
<p>这一节我们讲如何用ASMSupport生成方法调用的操作,方法调用包括下面四种类型:</p> <ol> <li>调用构造方法 <li>调用静态方法 <li>调用非静态方法 <li>调用当前类的方法 <li>调用父类方法</li></ol> <p>首先我们需要看我们想要生成的类:</p> <p>代码1:</p> <h3> <div id="scid:9D
helloworld_28799839 helloworld_28799839
2个月前
常用知识整理
# Javascript ## 判断对象是否为空 ```js Object.keys(myObject).length === 0 ``` ## 经常使用的三元运算 > 我们经常遇到处理表格列状态字段如 `status` 的时候可以用到 ``` vue
helloworld_34035044 helloworld_34035044
4个月前
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。 uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid() 或 uuid(sep)参数说明:sep 布尔值,生成的uuid中是否包含分隔符'',缺省为