Code Monkey home page Code Monkey logo

codemodeldemo's Introduction

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

codemodeldemo's People

Contributors

nuptboyzhb avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.