由于额外的括号,“赋值的左侧必须是变量”

问题描述 投票:0回答:2

我知道为什么以下代码无法编译:

public class Main {
   public static void main(String args[]) {
      main((null)); // this is fine!
      (main(null)); // this is NOT!
   }
}

我想知道为什么我的编译器(javac 1.6.0_17,Windows 版本)抱怨“赋值的左侧必须是变量”。

我希望得到类似“不要在方法调用周围加上括号,傻瓜!”的内容。

那么为什么编译器会对一些明显不相关的东西提出完全无益的抱怨呢?

这是语法歧义的结果吗?编译器中的错误?

如果是前者,你能设计一种语言,让编译器永远不会出现这样的语法错误吗?


好吧,我刚刚检查过,显然这个投诉只能在 Eclipse 中看到。如果我从命令行编译,它会给出更明智的“不是语句”错误。谜团加深了。

java eclipse compiler-errors
2个回答
4
投票

你的版本一定很奇怪。 :-P 在 OpenJDK(随 Ubuntu 9.10 一起发布)上进行测试时,我得到的是:

ParensTest.java:4: not a statement
        (main(null));
        ^
1 error

根据OP的编辑进行更新:Eclipse使用自己的Java编译器,称为

ecj
;它不使用 JDK 编译器 (
javac
)。这就是为什么有时会得到不同的输出。 (是的,生成的字节码有时也不同,导致奇怪的行为差异,具体取决于您是否在 Eclipse 中编译代码。)

(顺便说一句,根据我的经验,

ecj
javac
之间的另一个区别:如果你的字符串常量超过65535字节长,
javac
会告诉你迷路(这是类文件格式的限制)
ecj
实际上会尝试通过用
StringBuilder
将较短的部分拼凑在一起(每个部分都在 64k 限制内)来模拟如此长的字符串常量,然后最终将结果保留下来——就像“真实的”一样。 “ 字符串常量。)


3
投票

Java 编译器消息通常毫无帮助。它们只对编译器编写者真正有意义。

从解析器的角度来看,它获取一个表达式并到达唯一合法的事情要做的就是将其分配给一个变量,但没有一个变量,所以它放弃了。

您能设计更多有用的编译器消息吗?我想,但我怀疑 Sun/Oracle 会认为这是一个高优先级。

© www.soinside.com 2019 - 2024. All rights reserved.