59

在我当前的项目中,我们总是在 Java 源文件的末尾插入一个空的新行。我们还通过 CheckStyle(具有错误级别)强制执行此操作。

我一直在寻找这个主题,但不幸的是我找不到任何令人信服的理由。似乎其他开发人员对此很无动于衷,因为他们只是在 Eclipse 格式化程序中选中了一个复选框,并且它是自动完成的。但我仍然不知道为什么需要它以及为什么它很重要。所以我的问题是:

为什么需要 Java 源文件末尾的空行?它是当前的需求还是过去的遗物,在当前的代码库中是不可取的?

4

9 回答 9

40

我认为他们试图确保每个文件都以尾随换行符结尾。这不同于以空行结尾,也就是空换行符。

编辑:正如@Easy Angel 在评论中简洁阐明的那样:尾随换行=“\n”和空白行=“\n\n”

我认为要么:

  1. 您的线索要么要求每个文件都以换行符结尾,但被误解为要求每个文件都以空行结尾(即以换行符结尾的空行),或者

  2. 他们试图通过实际强制每个文件以空行结尾(也就是以换行符结尾的空行)来确保每个文件都以换行符结尾,从而确保文件以至少一个换行符结尾(并且可能是多余的附加换行符 - 过度杀伤力?)。

除非编辑器实际显示换行符,否则在某些编辑器中并不总是清楚文件:

  1. 根本不结束换行符,
  2. 以单个尾随换行符结尾,
  3. 以空白换行符结尾,即 2 个尾随换行符

我认为大多数现代源代码编辑器都会插入一个尾随换行符。但是,当使用较旧的更通用的编辑器时,我总是会尝试确保我的源代码文件(以及一般的文本文件)总是以尾随换行符结尾(根据我的编辑器,偶尔会出现空行/空换行符)使用)因为:

  1. cat用于在命令行上显示文件时,如果文件缺少尾随换行符,则下一个输出(如 shell 提示符或脚本可能在文件之间输出的视觉分隔符)最终会出现在最后一个非换行符之后而不是从换行开始。通常,尾随换行符使文件对用户和脚本更加友好。

  2. 我相信如果文本文件缺少一个尾随换行符,一些编辑器(我不记得任何细节)会自动插入一个尾随换行符。这将使它看起来像文件被修改。如果您在不同的窗口中打开了一堆文件然后关闭所有文件,这会让人感到困惑 - 编辑器会提示您保存,但您不确定您是否对文件进行了“真正的更改”或它只是自动 -插入换行符。

  3. 一些工具diff和一些编译器会抱怨缺少尾随换行符。这是用户和工具可能不得不处理的更多噪音。


编辑:

关于编辑器添加换行符并且无法查看文件末尾是否有换行符和空白换行符,我刚刚测试了 Vim、Eclipse 和 Emacs(在我的带有 Cygwin 的 Windows 系统上):我打开了一个新文件,键入 ' h' 'e' 'l' 'l' 'o' 并保存而不按 [ENTER]。我用 . 检查了每个文件od -c -t x1

  1. Vim 确实 添加了一个尾随换行符。
  2. Emacs 确实 添加了一个尾随换行符。
  3. Eclipse没有添加尾随换行符。

  1. Vim不允许我将光标向下移动到 "hello" 下的空白行。
  2. Emacs确实允许我将光标向下移动到“hello”下的空白行。
  3. Eclipse不允许我将光标向下移动到“hello”下的空白行。

随心所欲地解释。


我个人的做法是尽量确保文本文件以尾随换行符结尾。我只是觉得这种情况对人和工具来说是最不令人惊讶的。在这方面,我不会将源文件与文本文件有任何不同。

谷歌出现了这个

其中,截至本次编辑,显示有关来自 C 编译器、svn(由于 diff)、diff 等的缺少尾随换行符的警告的点击。我觉得人们普遍期望文本文件(包括源文件)以当它们往往存在时,尾随换行符和最不令人惊讶(且噪音较小)。

最后很有趣:

清理没有尾随换行符
的文件 文本文件的所有行都应该由换行符终止(即,\n)。这是由 POSIX 声明的,它表示文本文件是

包含组织成零行或多行的字符的文件。
一行又被定义为
* 零个或多个非字符加上一个终止字符的序列。


然而,说了这么多,这只是我个人的做法。我很高兴向任何提出要求的人分享我的意见,但我不会把这个强加给任何人。我不觉得这是值得强制执行的事情,就像我在这里说的:

虽然我是一个追求一致性的人,但我也反对对每一种风格进行微观管理。拥有大量编码约定,特别是当其中一些看起来随意时,是阻碍人们遵循它们的部分原因。我认为编码指南应该简化为最有价值的改进实践。通过强制执行这种做法,可读性、可维护性、性能等提高了多少?

于 2011-01-15T16:41:11.580 回答
29

这是在末尾有额外换行符的一个很好的理由:

如果您的文件末尾没有换行符,那么下次编辑该文件以添加另一行时,大多数合并工具会认为现有行已更改(我 90% 肯定 SVN 也会这样做)。

在下面的示例中,包含“编辑前的最后一行”的行没有换行符。如果我们尝试添加一个新行“编辑后的最后一行”,我们可以看到第 5 行和第 6 行都被标记为已更改,但两个版本中第 5 行的实际内容是相同的。

在 EOF 之前没有换行符

如果每个人都遵循您的项目负责人建议,那么这就是结果(只有第 6 行与原始文件不同)。这也避免了合并期间的误解。

在 EOF 之前使用换行符

虽然这看起来没什么大不了的,但假设一位开发人员 (A) 实际上打算更改最后一行的内容,而另一位开发人员 (B) 添加了一个新行。如果在 EOF 之前不使用换行符,那么您将遇到合并冲突,因为开发人员 B 被迫也编辑前最后一行以添加换行符。还有……谁喜欢 CVS/SVN 冲突?

于 2013-01-31T23:29:46.583 回答
7

看看这个 SO question。.

从拉尔夫·里肯巴赫那里无耻地窃取了答案:

如果文本文件中的最后一行数据未以换行符或回车符/换行符组合终止,则许多较旧的工具会出现异常。他们忽略该行,因为它以 ^Z (eof) 终止。

所以我认为这主要是过去的幽灵。不幸的是,如果你没有正确地驱除这些鬼魂,它们可能会咬你的尾巴。(您的构建服务器是否旧并使用旧的 shell 脚本进行摘要等)。

于 2011-01-15T15:28:16.317 回答
2

除了已经提到的使用尾随换行符的正当理由(旧工具和差异可能存在问题)之外,还有另一种看待它的方法:

当文件中的所有其他行都有换行符时,为什么附加换行符来对最后一行进行特殊处理?

于 2013-02-21T22:58:01.163 回答
2

尝试剪切/粘贴整个文件。checkstyle或eclipse中的一些错误:)

于 2011-02-16T15:35:59.793 回答
1

有时您的编译器无法正确解析它:

Error: Reached end of file while parsing

于 2011-01-15T16:42:40.033 回答
0

这只是一种编码风格。不会伤害或帮助任何事情。我不会让它打扰您,这听起来像是您的团队偏好包含和空行。除了为什么有人足够关心将它实际添加到 checkstyle 之外,没有真正的反对它的好论据?

于 2011-01-15T15:23:49.647 回答
0

我从来没有听说过这样的要求。

事实上,我刚刚确认,当文件末尾没有空行时,Java 程序将在没有任何编译器/运行时错误或警告的情况下运行。

正如一些评论者所说,这一定是编码风格问题。不幸的是,我无法说明为什么在 Java 中的文件末尾有一个空行可能很重要。事实上,这对我来说似乎完全没有意义

于 2011-01-15T15:27:30.333 回答
0

我们必须对一些 C++ 代码执行此操作,因为编译器会生成有关它的警告,并且我们有“无错误或警告”策略。也许问题出在其他地方......您是否有一个差异工具已经失控或无法处理它的合并工具?

这真的没什么大不了的。

于 2011-01-15T15:50:47.797 回答