什么是CommentProcessor
CommentProcessor是一个用Java实现的java源代码注释预编译器,它可以将带有特定注释语法的java源文件进行预编译,生成预编译后的java源代码。
第一次接触CommentProcessor是因为有一个J2ME游戏的移植项目中使用到了"iamp.jar"这样一个包,并且在JBuilder工程中有一个预编译选项使用了这个包。再检查源代码,看到很多诸如 "//#ifdefine", "//#endif", "/*$WIDTH$*/"等等这样的注释代码出现在源代码中,于是上网查了一下与"iamp.jar"相关的资料,找到了它的作者的站点http://igormaznitsa.com/,在那里可以下载免费使用的Java Comment Processor。
CommentProcessor的用途
使用CommentProcessor可以将Java源代码中符合预编译语法规范的注释进行预编译,这样做可以利用技巧做到:
- 在编译打包之前裁剪掉不需要的代码
- 通过预编译定义文件修改代码的内容,如数字、字符串等常量
- 包含其它文件到源代码中
- 进行一些简单的数据运算
- 等等
CommentProcessor适合什么项目
也许有人会说,这些工作在Java中是不必要的,因为我们可以通过继承、多态等特性来实现它,但在移动设备上的开发通常只允许你编译出50K以内的目标代码,每次新添加一个空类至少会增大500byte左右,而增加一个常规的继承类则会增加1KB-2KB的目标代码量。所以,在移动设备上,尤其是受限平台上的开发,对这方面要求尤其高,所以我们需要一个预编译器来整理我们的源代码。
同时,由于移动平台个体的差异性,不同型号的终端具有不同的设备特性,如屏幕分辨率、JSR标准的实现方法、设备本身的BUG等因素造成不同的平台上的代码会有小范围的差异,于是我们应该针对每个不同平台进行相应的代码优化。如果不使用预编译器,则可能造成为每一种型号的终端维护一份完整的代码,造成修改的不便。所以我们需要一个预编译器来协助维护不同平台上的特定代码。
适合使用CommentProcessor的项目特点:
- 使用Java实现
- 受限平台上的开发,要求很小的目标代码量
- 需要在多种设备平台间移植
CommentProcessor使用技巧范例
在下载的打包文件中有经典的HelloWorld范例程序和简单的帮助文档,在这里将HelloWorld展示给读者,同时作一些说明。
- 建立HelloWorld项目,编写源代码
//hello.java
public class hello {
//#include ".//test//_MainProcedure.java"
//通过上边这句代码可以在预编译过程中将".//test//_MainProcedure.java"的内容拷贝到hello.java中来
public static final void testproc() {
System.out.println( /*$VARHELLO$*/ );
//通过预编译可以将/*$VARHELLO$*/转换为预编译常量定义文件中("varlist.lst")所定义的内容
System.out.println( "// Hello commentaries" );
}
}
//test._MainProcedure.java
//#excludeif true
//上边这句代码表示不会将该Java文件作为一个源代码文件输出到输出文件夹
//#-
package test;
//#+
// //#-表示从该位置开始停止输出文件到输出流
// //#+表示从该位置开始恢复输出文件到输出流
//#prefix+
import java.util.Vector;
//#prefix-
//被//#prefix+和//#prefix-所包含的内容将被添加到输出文件的头部
//#-
public class _MainProcedure {
//#+
public static final void main(String [] args) {
System.out.println( /*$HelloWorld$*/ );
//这里的/*$HelloWorld$*/将在预编译时以命令行的形式给出
}
//#-
}
//#+ - 编写预编译常量定义文件"varlist.lst"
在"varlist.lst"里面定义了"VARHELLO"变量的值,同时该值引用自文件"./helloeng.txt"
VARHELLO=@"./helloeng.txt"
@"./helloeng.txt"意味着复制该位置的文件内容作为字符串 - 编写helloeng.txt的内容:
"Hello world" - 运行预编译器:
java -jar iamp.jar @./varlist.lst /R /N /I:./Example /O:./preprocessed /P:HelloWorld=$/$Hi/$$
pause
注意/P选项mane=value中的value表示字符串的时候要用$而不要使用' " '(双引号) - 预编译结果:
import java.util.Vector;
public class hello {
public static final void main(String [] args) {
System.out.println("Hi");
}
public static final void testproc() {
System.out.println("Hello world");
System.out.println( "// Hello commentaries" );
}
}
CommentProcessor应用效果
这里列举出一个实际的项目在应用CommentProcessor的前后区别对比
项目需求
- 编写环境:JBuilder2005 + Nokia J2ME SDK + MOTO J2ME SDK
- 编译版本:NokiaS40, Nokia7210, Nokia7610, Nokia7650, Nokia6600, SonyEricssonK700c, Motorola V525
- 特点:不同平台具有不同分辨率、某些方法具有不同的实现、不同平台容量不同、不同平台关卡设计有区别,但绝大部分是相同或相似的代码
应用CommentProcessor之前
- 进行NokiaS40版本的编写并调试通过;
- 为每个版本复制一份代码,进行相应的局部修改;
- 每次重新打包需要手动为每个项目进行Rebuild
- 当需要修改某块共有的代码时,需要将全部版本的代码全部修改一遍再重新编译生成(最艰难也是最易出错的步骤);
特点:
- 步骤多、繁琐、易出错;
- 维护了多套源代码,浪费了资源,导致项目混乱;
应用CommentProcessor之后
- 进行NokiaS40版本的编写并调试通过;
- 当需要进行另一个版本的编写时,新建一个预编译定义文件,并仅针对需要修改的部分进行预编译定义的包装(如用//#ifdefine 和//#endif包装),并重新预编译生成各版本的代码;
- 建立项目组共享一套预编译之前的代码,根据不同项目生成不同的预编译源代码,实现"One Key Rebuild";
- 当需要修改某块共有的代码时,仅修改唯一一套预编译之前的源代码,重新生成项目组即可预编译成不同版本的更新版;
特点:
- 维护唯一一套源代码(预编译之前)
- One Key Rebuild All
- 高效、少出错、步骤简洁
参考资料
“官方”下载:http://igormaznitsa.com/