Java源代码中的“机械生成”java源文件
Posted
技术标签:
【中文标题】Java源代码中的“机械生成”java源文件【英文标题】:"Mechanically generated" java source files in the Java source code 【发布时间】:2014-07-23 07:14:50 【问题描述】:在查看 Java 源代码时,我发现了一些不寻常的文件,主要与 java.nio
包中的 ByteBuffer
s 相关,这些文件的源代码非常混乱,并被标记为 This file was mechanically generated: Do not edit!
。
这些文件还包含大部分空行(有些甚至在 javadocs (!!?) 的中间),大概是为了防止行号发生变化。我还看到了一些 java 反编译器,例如 procyon-decompiler
,它们可以选择保留行号,但我怀疑情况是否如此,因为在最终荣誉之前放置空行不会改变任何事情。
这里是其中的一些文件(我在网上找不到指向它们的任何链接,也没有粘贴它们,因为我不想破坏任何版权,但您可以在 src.zip
文件夹中找到它们JDK 安装文件夹的根目录):
我很想知道:
哪些工具生成了这些文件? 为什么该工具保持行号相同?是否让调试(堆栈跟踪)更容易? 为什么要使用工具来生成它们,而所有其他类都是由人类编程的? 为什么该工具会在括号内随机放置空行,在最后的荣誉之前,甚至在 javadocs 中?【问题讨论】:
我怀疑你会得到答案,因为该代码似乎已经存在了很长时间 - 请查看 this blog post from 2006,当时 Java 仍归 Sun 所有。 这些文件似乎是在构建过程中由一些预处理器从模板文件中生成的:hg.openjdk.java.net/jdk9/dev/jdk/file/3b298c230549/src/share/… IIRC,C 预处理器由于在#if 或#else 之后跳过而插入空行。在这里,我认为基本原理很清楚:如果某些编译器在输出中标记错误,您会在原始输入中找到它。 【参考方案1】:我可能无法回答所有问题,但一些背景是:
在http://hg.openjdk.java.net/jdk7/jdk7/jdk/file/9b8c96f96a0f/make/java/nio/Makefile的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
等类型化缓冲区的来源。
注意:网址将来可能会更改。也很抱歉提到 Java 7 - 在 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。
为什么要使用工具来生成它们,而所有其他类都是由人类编程的?
我没有这个具体案例的权威答案,但通常你使用的是代码生成工具
如果您需要创建许多类似的类/方法,它们只是在某些细节上有所不同,但它们足够微妙,以至于您不能使用已建立的机制,如泛型或方法参数(可能是这里的情况,因为缓冲区是为不能与泛型一起使用的原始类型生成) 如果您需要从更简单的表示创建复杂的算法(例如从语法生成解析器)。为什么该工具保持行号相同?是否让调试(堆栈跟踪)更容易?
我猜:是的,它保留堆栈跟踪中的行号,以便它们与模板文件匹配。 C
预处理器等其他工具的工作原理类似。
【讨论】:
是的,这些类对于原始类型(short、char、...)是多样化的。一个罕见的案例。有一些调查将原始类型包装在一些未来的 java 中,所以你可以有Buffer<int>
。以上是关于Java源代码中的“机械生成”java源文件的主要内容,如果未能解决你的问题,请参考以下文章
mybatis报错:java.lang.IllegalArgumentException: invalid comparison: java.util.Arrays$ArrayList and jav