在 Java 源文件末尾清空新行

2022-08-31 16:12:24

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

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

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


答案 1

我认为他们试图确保每个文件都以尾随换行符结尾。这与以空行(又称空换行符)结尾不同。

编辑:正如@Easy Angel在评论中简洁地澄清的那样:尾随换行符=“\n”,空行=“\n\n”

我认为要么:

  1. 您的潜在客户要么强制要求每个文件都以换行符结尾,但被误解为强制要求每个文件都以空行结尾(即以换行符结尾的空行),要么

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

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

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

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

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

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

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


编辑:

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

  1. Vim 确实添加了一个尾随换行符。
  2. Emacs did add a trailing newline.
  3. Eclipse did NOT add a trailing newline.

But

  1. Vim did NOT allow me to cursor down to a blank line under "hello".
  2. Emacs did allow me to cursor down to a blank line under "hello".
  3. Eclipse did NOT allow me to cursor down to a blank line under "hello".

Interpret as you like.


My personal practice is to try to ensure text files end with a trailing newline. I just feel there's the least surprise to people and tools with this is the case. I wouldn't treat source files any different from text files in this respect.

Google turns up this:

which, as of this edit, show hits that talk about warnings about a missing trailing newline coming from C compilers, svn (because of diff), diff, etc. I feel there's a general expectation that text files (source files included) end with a trailing newline and least surprising (and less noisy) when they tend to be there.

Finally this is interesting:

Sanitizing files with no trailing newline
Text files should have all their lines terminated by newline characters (ie, \n). This is stated by POSIX, that says that a text file is

A file that contains characters organized into zero or more lines.
A line, in turn, is defined as
* A sequence of zero or more non- characters plus a terminating character.


HOWEVER, all that said, this is just my personal practice. I'm happy to share my opinion to anyone that asks, but I don't foist this on anyone. I don't feel this is something worth mandating, like I say here:

While I'm one whose all for consistency, I'm also against micromanaging every bit of style. Having a huge list of coding conventions, particularly when some of them seem arbitrary, is part of what discourages people from following them. I think coding guidelines should be streamlined to the most valuable practices that improve the -ilities. How much is readability, maintainability, performance, etc improved by mandating this practice?


答案 2

Here is a good reason for having extra line-break at the end:

If you have a file without line-break at the end, next time the file is edited to add another line, most of merge tools will think that the existing line has changed (I'm 90% sure SVN also does).

In the example below, the line containing “last line before edit” does not have the line break. If we try to add a new line “last line after edit”, as we can see both lines 5 and 6 are marked as changed, but actual contents of line 5 in both versions are the same.

Without line-break before EOF

If everyone is following your project lead suggestion, then this would be the result (only line 6 differ from original file). This also avoids misunderstandings during merges.

With line-break before EOF

While this may not look like a big deal, let's say one developer (A) actually meant to change the contents of the last line and another developer (B) added a new line. If not using line-break before EOF, then you have a merge conflict because developer B was forced to also edit the former last line to add a line-break. And... who likes CVS/SVN conflicts?


推荐