据说Java忽略了额外的空格.为什么c = a ++ + ++ b如果没有空格就不能编译?

Joh*_*son 4 java whitespace parsing operator-precedence post-increment

在所有关于Java的书籍中,我都读到编译器以相同的方式处理所有空格并简单地忽略了额外的空格,因此最好的做法是大量使用它们来提高代码的可读性.我已经在我写过的每一个表达中找到了证据:无论是否有空格都没关系,有多少(或者我只是没注意).

最近我决定尝试运算符优先级和关联性来测试优先级表并尝试编译

int a = 2;
int b = 3;    
int c = a+++b;
int d = a+++++b;
Run Code Online (Sandbox Code Playgroud)

虽然前一个陈述完美汇编,但后者产生了一个例外:

线程"main"中的异常java.lang.RuntimeException:无法编译的源代码 - 意外类型.必需:变量.发现:价值.

但是,当我添加空格:时int d = a++ + ++b,它编译.为什么会这样?据说Java无论如何都会忽略额外的空格.(如果这很重要,我有Java 8和Netbeans IDE 8.2.)

我想这可能与解析表达式有关,但我不确定.我尝试在SO和Google上查找有关解析,空白和运算符的几个问题,但找不到明确的答案.

UPD.为了解决那些重要的"额外"的评论,而不是所有的空白:既然int c = a++ + b;int c=a+++b;编译,可以说,通过类比,在int d = a ++ + ++b;空白中也是"额外的".

Dan*_*den 7

Java语言规范第3.2节 "词汇翻译"说(强调我的):

使用以下三个词汇翻译步骤将原始Unicode字符流转换为一系列标记,这些步骤依次应用:

  1. 的翻译Unicode转义 [...]

  2. 翻译成输入字符和行终止符流[...].

  3. 将步骤2产生的输入字符和行终止符流转换为输入元素序列(第3.5节),在输出元素(第3.6节)和注释(第3.7节)之后,它们包含令牌(§3.5)这是句法语法的终点符号(§2.3).

每个步骤都使用尽可能长的翻译,即使结果最终没有形成正确的程序而另一个词汇翻译也会如此.

因此,在确定"输入元素序列"之后,丢弃空白字符.第3.5节"输入元素和令牌"说:

空格(§3.6)和注释(§3.7)可用于分隔令牌,如果相邻,则可以用其他方式对其进行标记.例如,只有在没有插入空格或注释的情况下,输入中的ASCII字符 - 和=才能形成运算符标记 - =(§3.12).