Java 的多行字符串 Here Document 的实现

寻求了很久关于如何在 Java 中实现多行字符串,即 Here Document。因为在测试中准备大的字符串数据是不得不用加号去拼接,甚至是麻烦。稍好就是用 http://www.htmlescape.net/javaescape_tool.html 把你输入的大段文字生成 Java 的字符串。

找过一些介绍 Java 实现 Here Document 的方法,首先大家无一不是把这个多行字符串塞在注释里,有些实现在运行还在依赖于 Java 源文件中的注释,这不太可取。聪明的做法应该要去打编译器的主意,让编译后体现在 Class 文件中,变量就被赋上了多行字符串值,这就是 JDK1.5 引入的 APT(Annotation Processing Tool),到 JDK1.6 后可操作性更强了,可以 javac 的时候带上 -processor 参数。

单单从语法特性上来讲,我觉得 Java 与现今流行的语言还是有差距,不过它一直在成长,像 JDK 1.5 和 1.7 这两个版本就带来了不少好东西。想要见识一下其他些个语言,如 Perl, PHP, Ruby, C++11 怎么实现 Here Document 还是请看 http://en.wikipedia.org/wiki/Here_document

就连 Java 最亲密的战友 C# 都早实现了 Here Document,用 @ 符号:

现在正式来看 Java 应用 APT 如何实现 Here Document 的,会建立两个项目,分别是 HereDocument 和  HereDocumentTest,前者是实现,后者是对它的测试,必须分成两个项目,因为编译后者的时候,前者的 Class 文件必须先存在。

为方便起见,都做成 Maven 项目,下面来展示它们。

1. HereDocument 项目:

1) pom.xml:

代码中要用到 tools.jar 中的实现类,所以必须引入,Mac OS 下的相应的类可能在 ${java.home}/../Classes/classes.jar 中。

2) HereDocument 注解

3) HereDocumentProcessor

上面代码完成后运行 mvn clean install 把生成的 jar 包安装到本地库中,下面的 HereDocumentTest 要依赖于它。

2. HereDocumentTest 项目

1) pom.xml:

本项目引入了 HereDocument 生成的 jar 包,在插件中配置了 annotationProcessor 就是前面的 cc.unmi.apt.HereDocumentProcessor。

2) Client.java

3) HereDocumentTest.java

现在来看用 Maven 运行 HereDocumentTest 项目的效果,先命令行进到 HereDocumentTest 所在目录,为确保 Class 文件是由 Maven 编译出来的,先运行:

mvn clean compile

然后执行

mvn exec:java, 输出:

heredoc_1用 mvn exec:java 运行的是 cc.unmi.apt.Client 代码,因为用到了 Maven 的 exec-maven-plugin 插件。

也可以运行

mvn test

执行的是 cc.unmi.apt.HereDocumentTest 中的测试用例,也看效果:

heredoc_2

那到底应用了 HereDocumentProcessor 发生了什么,查看一下生成的 Client.class 文件:

heredoc_3

只截了个屏,不完整,但发生的事情很简单,就是 HereDocumentProcessor 把代码中对 html 变量用它上头的注解内容给赋了值。

因为使用 APT 使你瞄上了 Java 编译器,所以有些时候用起来会麻烦些,特别是在使用 IDE 的时候。

像命令行编译时

javac -processor <annotation processor class1>, [<annotation processor class2>] -processorpath <path, processor 的 classpath>

比如说以上的 HereDocument.class 和  HereDocumentProcessor.class 打包在 c:\heredoc.jar 包中,编译 Client.java 就用命令:

javac -processor cc.unmi.apt.HereDocumentProcessor -processorpath c:\heredoc.jar -classpath .;c:\heredoc.jar Client.java

然后执行

java Client

在 Eclipse 中配置 Project Properties 里的 Java compiler /  Annotation Processing

注:如果按照上面的方法在 Eclipse IDE 中配置来使用 Processor,那么 init() 方法中的 procEnv 的类型是 org.eclipse.jdt.internal.apt.pluggable.core.dispatch.IdeBuildProcessingEnvImpl,而不是  JavacProcessingEnvironment,并且它们之间不存在父子关系,无法进行转型,会有异常。

在 NetBeans 配置 Project Properties / Build / Compiling / Annotation Processors

参考: 1. Java Multiline String
           2. Using Java 6 processors in Eclipse
           3. Annotation Processors Support in the NetBeans IDE

本文链接 https://yanbin.blog/java-implement-here-document/, 来自 隔叶黄莺 Yanbin Blog

[版权声明] Creative Commons License 本文采用 署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0) 进行许可。

Subscribe
Notify of
guest

5 Comments
Inline Feedbacks
View all comments
trackback

[…] Java 的编译期  AnnotationProcessor 的方式: Java 的多行字符串  Here Document 的实现。后来完全对此失望了,Java […]

Anonymous
Anonymous
7 years ago
Reply to  Yanbin

Here Document 的这个实现用起来不方便。
1. 比如依赖的注解要求字符串必须是一个成员变量,不能用在任意地方,比如函数内
2. 在Eclipse下不能够格式代码(Ctrl+Shift+F), 会破坏注释的内容(要避免需用@formatter:on/off,很麻烦)
3. 编译的时候也需要设置processor
4. 如processor没有正常工作,容易出现空字符串, 而且还难以发现问题。

Yanbin
7 years ago
Reply to  Anonymous

Java 原生不支持,其他变着法来弄的都优雅不起来。我现在对 Java 的 Here Doc 没有什么追求了,因为可以在项目中使用 Scala 了。