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] 官方文档

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
HuggingFace是一个开源的自然语言处理(NLP)模型库,提供了各种预训练的AI模型。您可以通过访问HuggingFace的官方网站或GitHub页面来使用它们。引用 使用HuggingFace的Demo非常简单。您可以通过以下步骤来使用HuggingFace的Demo: 1. 首先,您需要打开HuggingFace的官方网站或GitHub页面,找到您感兴趣的Demo模型。 2. 在Demo页面,您可以看到模型的描述和用法说明。这些说明将帮助您理解如何使用Demo模型。 3. 接下来,您可以使用提供的示例代码或命令行指令来运行Demo。这些示例代码或指令通常会在文档中提供。 4. 根据需要,您可以在Demo中输入相应的文本或参数。这些输入将作为模型的输入,模型会根据这些输入生成相应的输出。 举个例子,如果您想使用HuggingFace的ChatGPT模型进行对话,您可以通过编写代码或使用命令行指令来启动Demo。然后,您可以输入要与模型对话的文本,并查看模型生成的响应。引用 另外,HuggingFace还提供了其他类型的Demo。例如,它使用了名为「runwayml/stable-diffusion-1-5」的模型来生成跳舞的猫的图片。您可以根据Demo文档中提供的说明和示例代码来使用这个功能。引用 总结起来,要使用HuggingFace的Demo,您需要找到相应的模型,并按照Demo文档中的说明进行操作。您可以通过提供输入来与模型交互,并查看生成的输出结果。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值