JCodeModel使用Demo

CodeModelDemo

A demo of JCodeModel

CodeModel代码生成

常用类

在 CodeModel中,常用的类有JCodeModel、JDefinedClass、JMethod、JBlock、JFieldVar、JVar、JType、JExpr 等。

JCodeModel

JCodeModel 类是生成 Java 代码的根。通过它生成JDefinedClass类,然后再生成构造方法、成员变量、方法以及方法体等。从上而下,依次生成。

    JCodeModel codeMode = new JCodeModel();
    JDefinedClass genClass = codeMode._class("com.example.test.TestMain",
                ClassType.CLASS);
    ...
    codeModel.build(new File("src"));

上述代码片段就会在src目录下,生成一个TestMain类

1.JDefinedClass

JDefinedClass类是通过CodeModel来定义类的,它提供了类自身的创建、继承、实现,以及类成员变量、成员方法的创建方法等

    genClass._extends(Student.class);
    genClass._implements(Serializable.class);

如上代码是继承Student类,实现Serializable接口

2.JMethod

JMethod 类是Java的方法类,它可以创建方法体,那么就有了JBlock类

    JMethod jMethod = genClass.method(JMod.PUBLIC + JMod.STATIC,
                void.class, "fun");// public static void fun()
    jMethod.param(codeModel.parseType("String"), "str1");
    jMethod.param(codeModel.parseType("String"), "str2");

上述代码,首先生成了一个fun方法,然后分别生成了两个参数,生成的代码是:

    public static voud fun(String str1,String str2){
    }

3.JBlock

JBlock类是经常要用到的类,它提供了非常多的方法:局部变量的声明、变量赋值、生成各种控制语句、调用其他方法、设置方法的返回值等。上面代码,我们已经可以生成方法了,但是方法中的内容怎么生成呢?

    JBlock block = jMethod.body();//获取方法的方法体
    JVar nameVar = block.decl(codeModel.parseType("Student"), "name");//声明一个局部变量

生成的代码如下:

    public static void fun(String str1, String str2) {
        Student name;
    }

4.JFieldVar

JFieldVar类用来定义类的成员变量,它可以对成员变量进行声明、赋值等

    JFieldVar sFieldVar = genClass.field(JMod.PRIVATE + JMod.STATIC,
                codeModel.INT, "sCount", JExpr.lit(10));

生成的代码:

    private static int sCount = 10;

5.JVar

JVar类用来定义局部变量,提供了变量的基本操作如声明、赋值、初始化等

    JBlock block = jMethod.body();
    JVar nameVar = block.decl(codeModel.parseType("Student"), "name");
    block.assign(nameVar,JExpr._new(codeModel.parseType("Student")));

生成赋值的代码:

    public static void fun(String str1, String str2) {
        Student name;
        name = new Student();
    }

6.JType

JType 类用来定义Java中的各种数据类型
常用的类型,比如int,void等基本类型,可以通过codeModel获取,比如codeModel.INT,codeModel.VOID等。如果是自定义类型,比如Student类。

    JType type = codeModel.parseType("Student");

7.JExpr

JExpr 类表达式的工厂类,它提供了 TRUE 和 FALSE 两个常量值,以及生成表达式的各种方法以及表达式的赋值等

8.JMod

主要是方法或者成员变量的属性,比如private、public、static、synchronized等,使用‘+’连接符。

举例

源码地址:https://github.com/nuptboyzhb/CodeModelDemo.git

例如,如下代码是生成一个Utils类

    public class GenUtilsDemo {

    public static void main(String[] args) {
        try {
            genClass();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void genClass() throws Exception {
        JCodeModel codeMode = new JCodeModel();
        File destDir = new File("src");// 代码生成的目录
        JDefinedClass genClass = codeMode._class("net.mobctrl.aa.Utils",
                ClassType.CLASS);// 生成Utils类
        genClass._implements(Serializable.class);
        // 生成静态成员变量
        JFieldVar sUtilsField = genStaticField(codeMode, genClass);
        // 生成私有构造方法
        genPrivateConstructor(codeMode, genClass);
        // 生成单例
        genGetInstanceMethod(codeMode, genClass, sUtilsField);
        // 生成fun方法
        genFunMethod(codeMode, genClass);
        // 生成filter方法
        genFilterMethod(codeMode, genClass);

        codeMode.build(destDir);
    }

    /** * 生成代码 * * <pre> * private void filter(int[] datas, int bottom) { * for (int i = 0; i &lt; datas.length; i++) { * if (datas[i] &gt; bottom) { * System.out.println(datas[i]); * } * } * } * </pre> * * @param codeMode * @param genClass */
    private static void genFilterMethod(JCodeModel codeMode,
            JDefinedClass genClass) throws Exception {
        JMethod filterMethod = genClass.method(JMod.PRIVATE,
                codeMode.parseType("void"), "filter");// 生成方法
        filterMethod.javadoc().add("doc: filter datas");//添加注释
        filterMethod.param(codeMode.parseType("int []"), "datas");// 添加参数int []
                                                                    // datas
        filterMethod.param(codeMode.parseType("int"), "bottom");// 添加参数int
                                                                // bottom


        JBlock methodBody = filterMethod.body();
        JForLoop forLoop = methodBody._for();// 生成for循环
        forLoop.init(codeMode.parseType("int"), "i", JExpr.lit(0));// 循环的初始 int
                                                                    // i = 0;
        forLoop.test(JExpr.direct("i<datas.length"));// 循环条件:直接写表达式
        forLoop.update(JExpr.ref("i").incr());// 每次循环

        JBlock forBody = forLoop.body();// 获取for循环的内部体
        JConditional ifConJConditional = forBody._if(JExpr.ref("datas[i]").lt(
                JExpr.ref("bottom")));// 在for循环中生成if(datas[i]<bottom)条件语句
        JBlock ifBody = ifConJConditional._then();// 获得if的模块体
        JBlock elseBody = ifConJConditional._else();// 获得else的模块体

        JClass sys = codeMode.ref("java.lang.System");
        JFieldRef out = sys.staticRef("out");
        ifBody.invoke(out, "println").arg(JExpr.ref("datas[i]"));

        elseBody._continue();
    }

    /** * 生成代码 * * <pre> * public void fun() { * int[] datas = new int[] { 5, 6, 7, 2, 8, 9 }; * int bottom = 7; * filter(datas, bottom); * } * </pre> * * @param codeMode * @param genClass */
    private static void genFunMethod(JCodeModel codeMode, JDefinedClass genClass)
            throws Exception {
        JMethod funMehtod = genClass.method(JMod.PUBLIC,
                codeMode.parseType("void"), "fun");// 生成返回值类型为void的fun方法
        JBlock methodBody = funMehtod.body();
        // 生成局部变量int []datas;
        JVar datasVar = methodBody.decl(codeMode.parseType("int []"), "datas");
        JArray initArray = JExpr.newArray(codeMode.INT); // 创建类型为整型的数组
        initArray.add(JExpr.lit(5));// 添加数据
        initArray.add(JExpr.lit(6));
        initArray.add(JExpr.lit(2));
        initArray.add(JExpr.lit(8));
        initArray.add(JExpr.lit(9));
        methodBody.assign(datasVar, initArray);// 在方法体中,对datasVar进行赋值

        JVar bottomVar = methodBody.decl(codeMode.parseType("int"), "bottom",
                JExpr.lit(7));// 生成初始值为7的int局部变量bottom

        JInvocation invocation = methodBody.invoke("filter");// 调用filter方法
        invocation.arg(datasVar).arg(bottomVar);// 依次传递参数 datasVar和bottomVar
    }

    /** * 生成代码 * * <pre> * public synchronized static Utils getInstance() { * if (sUtils == null) { * sUtils = new Utils(); * } * return sUtils; * } * </pre> * * @param codeMode * @param genClass */
    private static void genGetInstanceMethod(JCodeModel codeMode,
            JDefinedClass genClass, JFieldVar sUtilsField) throws Exception {
        JType utilsType = codeMode.parseType("Utils");// 生成一个名为Utils的类型
        JMethod jMethod = genClass.method(JMod.PUBLIC + JMod.SYNCHRONIZED
                + JMod.STATIC, utilsType, "getInstance");// 生成返回值Utils的名为getInstance的私有静态方法
        JBlock methodBody = jMethod.body();// 获得方法体
        JConditional ifConditional = methodBody._if(JExpr.ref("sUtils").eq(
                JExpr.ref("null")));// 生成if(sUtils == null)条件语句
        JBlock ifBody = ifConditional._then();// 获得条件语句的方法块
        ifBody.assign(sUtilsField, JExpr._new(utilsType));// 对sUtilsField进行赋值,新建一个Utils
        methodBody._return(sUtilsField);// 将成员变量sUtilsField返回
    }

    /** * 生成代码 * * <pre> * private Utils() { * super(); * } * </pre> * * @param codeMode * @param genClass */
    private static void genPrivateConstructor(JCodeModel codeMode,
            JDefinedClass genClass) {
        JMethod constructor = genClass.constructor(JMod.PRIVATE);// 生成构造方法
        JBlock blk = constructor.body();// 获取方法体
        blk.invoke("super");// 在方法体中调用super方法
    }

    /** * 生成代码: * * <pre> * private static Utils sUtils = null; * </pre> * * @param codeMode * @param genClass * @return * @throws Exception */
    private static JFieldVar genStaticField(JCodeModel codeMode,
            JDefinedClass genClass) throws Exception {
        JType utilsType = codeMode.parseType("Utils");// 生成一个名为Utils的类型
        JFieldVar sUtilsField = genClass.field(JMod.PRIVATE + JMod.STATIC,
                utilsType, "sUtils", JExpr._null());// 生成一个私有的静态成员变量,并赋值为null
        return sUtilsField;
    }

    }

生成的对应代码如下:

    package net.mobctrl.aa;

    import java.io.Serializable;

    public class Utils implements Serializable{

    private static Utils sUtils = null;

    private Utils() {
        super();
    }

    public static synchronized Utils getInstance() {
        if (sUtils == null) {
            sUtils = new Utils();
        }
        return sUtils;
    }

    public void fun() {
        int[] datas;
        datas = new int[] { 5, 6, 2, 8, 9 };
        int bottom = 7;
        filter(datas, bottom);
    }

    /** * doc: filter datas * */
    private void filter(int[] datas, int bottom) {
        for (int i = 0; (i<datas.length); i ++) {
            if (datas[i]<bottom) {
                System.out.println(datas[i]);
            } else {
                continue;
            }
        }
    }

    }

参考:

[1] 用 Java 生成 Java - CodeModel 介绍
[2] 官方文档

你可能感兴趣的:(java)