当我查看Java源码时,我发现一些特别的文件,主要涉及的有java.nio
包下的ByteBuffer
等类似的类,有舍非常凌乱的源码,还写着This file was mechanically generated: Do not edit!
,这些文件通过机器生成的,不要编辑!
这些文件包含了大量空行(有些升值在javadocs中),大概是为了防止行号更改,我也看过一些java反编译器,类似procyon-decompiler
,它有一个选项来保持行号,但我怀疑是这种情况,因为在最终accolade前添加空白行不会改变什么。
下面是其中一些文件(我在网上找不到它们的链接,也没有粘贴,因为我不想破坏任何版权,但你能在JDK安装文件夹根目录下的src.zip
中找到它们)
- java.nio.ByteBuffer
- java.nio.DirectByteBufferR
- java.nio.Bits
- java.nio.BufferOverflowException
我很想知道
- 什么工具生成的这些文件?
- 为什么工具要保持行号不变,为了更容易debugger吗?
- 为什么要使用工具生成它们,而其他所有类都是由人编写的?
- 略
我可能不能回答所有的问题,但一些背景是:
在Makefile的http://hg.openjdk.java.net/jdk7/jdk7/jdk/file/9b8c96f96a0f/make/java/nio/Makefile中,他们通过一些预处理程序从相同的模板文件生成不同的java源文件:
...
$(BUF_GEN)/CharBuffer.java: $(X_BUF_TEMPLATE) $(GEN_BUFFER_SH)
$(prep-target)
@$(RM) $@.temp
TYPE=char SRC=$< DST=$@.temp $(GEN_BUFFER_CMD)
$(MV) $@.temp $@
$(BUF_GEN)/ShortBuffer.java: $(X_BUF_TEMPLATE) $(GEN_BUFFER_SH)
$(prep-target)
@$(RM) $@.temp
TYPE=short SRC=$< DST=$@.temp $(GEN_BUFFER_CMD)
$(MV) $@.temp $@
...
$(X_BUF_TEMPLATE)
指的事 X-Buffer.java.template
, 它是诸如Charbuffer
、Shortbuffer
等类型缓冲区的源代码。
注意:URL将来可能会改变。也很抱歉引用了Java7。在Java 8中他们已经修改了构建系统,到目前为止我还没有找到相应的makefile。
什么工具生成的这些文件?
GEN_BUFFER_SH
/ GEN_BUFFER_CMD
最终指向了 genBuffer.sh
, 创建了这些文件的脚本是 http://hg.openjdk.java.net/jdk7/jdk7/jdk/file/9b8c96f96a0f/make/java/nio/genBuffer.sh.
为什么要使用工具生成它们,而其他所有类都是由人类编写的?
对于这种特殊情况,我没有权威的答案,但通常你使用代码生成工具可能由以下情况
- 如果你需要创建许多相似的类/方法,这些类/方法只在某些细节上有所不同,但非常微妙,因此您不能使用已建立的机制,如泛型或方法参数(可能是这里的情况,因为缓冲区是为不能与泛型一起使用的基本类型生成的)
- 如果需要从更简单的表示创建复杂的算法(比如从语法生成解析器)。
为什么工具要保持行号不变,为了更容易debugger吗?
我的猜测:是。它将行号保留在堆栈跟踪中,以便它们与模板文件匹配。其他工具比如C
预处理器工作原理类似。