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

Stella981
• 阅读 609

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/

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
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:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
待兔 待兔
4个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Jacquelyn38 Jacquelyn38
3年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
Stella981 Stella981
3年前
Android So动态加载 优雅实现与原理分析
背景:漫品Android客户端集成适配转换功能(基于目标识别(So库35M)和人脸识别库(5M)),导致apk体积50M左右,为优化客户端体验,决定实现So文件动态加载.!(https://oscimg.oschina.net/oscnet/00d1ff90e4b34869664fef59e3ec3fdd20b.png)点击上方“蓝字”关注我
Easter79 Easter79
3年前
Twitter的分布式自增ID算法snowflake (Java版)
概述分布式系统中,有一些需要使用全局唯一ID的场景,这种时候为了防止ID冲突可以使用36位的UUID,但是UUID有一些缺点,首先他相对比较长,另外UUID一般是无序的。有些时候我们希望能使用一种简单一些的ID,并且希望ID能够按照时间有序生成。而twitter的snowflake解决了这种需求,最初Twitter把存储系统从MySQL迁移
Stella981 Stella981
3年前
ASMSupport教程4.5 在Class中生成算术运算符
<h2ASMSupport教程4.5在Class中生成算术运算符</h2<p这节我们开始介绍ASMSupport如何生成算数运算符(\/%),依旧先看我们需要生成的java代码:</p<divid"scid:9D7513F9C04C4721824A2B34F0212519:22b13b06a0d64b8eb7cd768
Stella981 Stella981
3年前
ASMSupport教程4.9 生成三元运算符
<p这节我们介绍如何用ASMSupport生成三元运算符(...?...:...)运算符。我们预计生成如下代码:</p<divid"scid:9D7513F9C04C4721824A2B34F0212519:935e30cc33214e0093ba9834f3a4e044"class"wlWriterEditableS
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
10个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这