2014-07-23 78 views
9

当我浏览Java源代码时,发现了一些不寻常的文件,其中大部分与java.nio包中的ByteBuffer有关,该包中源代码非常混乱,并被标记为This file was mechanically generated: Do not edit!Java源代码中的机械生成的java源文件

这些文件还包含很大一部分空白行(有些甚至在javadocs(!!?)中),这大概是为了防止行号发生变化。我还看到了一些Java反编译器,例如procyon-decompiler,它们可以选择保留行号,但我怀疑是这种情况,因为在最终的赞美之前放空行并没有改变。

下面是这些文件中的一些(我在网上找不到任何链接,并没有粘贴它们,因为我不想打破任何版权,但是您可以在src.zip文件夹中找到它们你的JDK安装文件夹根):

  • java.nio.ByteBuffer中
  • java.nio.DirectByteBufferR
  • java.nio.Bits
  • java.nio.BufferOverflowException

我很好奇地想知道:

  • 哪些工具生成这些文件?
  • 为什么该工具保持行号相同?它是否使调试(堆栈跟踪)更容易?
  • 为什么要使用一个工具来生成它们,而所有其他类都是由人类编程的?
  • 为什么这个工具会在最后的荣誉之前,甚至在javadocs中,在括号内随机地放置空行?
+0

我怀疑你会得到一个答案,因为该代码看起来已经很长时间了,请查看[2006年的这篇博客文章](http://www.iggdawg.com/blog/2006/09/jaaaavaaaaa /),当时Java仍然归Sun所有。 – APC

+2

看起来这些文件是由模板文件中的某个预处理器生成的:http://hg.openjdk.java.net/jdk9/dev/jdk/file/3b298c230549/src/share/classes/java/nio/ ByteBufferAs-X-Buffer.java.template –

+0

IIRC,由于在#if或#else之后跳过,C预处理器会插入空行。在这里,基本原理很清楚,我认为:如果某个编译器在输出中标记了一个错误,您可以在原始输入中找到它。 – laune

回答

9

我也许可以不回答所有的问题,但有些背景是:

在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) [email protected] 
    TYPE=char SRC=$< [email protected] $(GEN_BUFFER_CMD) 
    $(MV) [email protected] [email protected] 
$(BUF_GEN)/ShortBuffer.java: $(X_BUF_TEMPLATE) $(GEN_BUFFER_SH) 
    $(prep-target) 
    @$(RM) [email protected] 
    TYPE=short SRC=$< [email protected] $(GEN_BUFFER_CMD) 
    $(MV) [email protected] [email protected] 
... 

$(X_BUF_TEMPLATE)指的是X-Buffer.java.template,它是CharBufferShortBuffer等一些类型缓冲区的来源。

注意:URL可能在将来发生变化。对于提到Java 7也很抱歉 - 在Java 8中,他们修改了构建系统,到目前为止我没有找到相应的Makefiles。

哪个工具生成这些文件?

GEN_BUFFER_SH/GEN_BUFFER_CMD终于是指genBuffer.sh,所以它创建这些文件的脚本是http://hg.openjdk.java.net/jdk7/jdk7/jdk/file/9b8c96f96a0f/make/java/nio/genBuffer.sh

为什么会使用一个工具来生成它们,而所有其他类都是由人类编程的?

我没有为这个特定的情况下,权威的答案,但通常你正在使用的代码生成工具

  • ,如果你需要创建很多相似的类/只在不同的方法一些细节,但它足够微妙,以至于你不能使用已建立的机制,如泛型或方法参数(这里可能是这种情况,因为缓冲区是为原始类型生成的,不能与泛型一起使用)
  • 如果需要从一个更简单的表示(例如生成解析器)创建复杂的算法从语法来看)。

为什么工具保持行号一样吗?它是否使调试(堆栈跟踪)更容易?

我猜测:是的,它保留堆栈跟踪中的行号,以便它们匹配模板文件。其他工具,如C预处理器的工作类似。

+1

是的,这些类对于原始类型(short,char,...)是多样化的。罕见的情况。有一些研究将原始类型包装在未来的java中,因此您可以使用'Buffer '。 –