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

时间:2010-03-24 03:06:56

标签: java eclipse parsing compiler-construction compiler-errors

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

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中看到。如果我从命令行编译,它会给出更明智的“Not a statement”错误。神秘感加深了。

2 个答案:

答案 0 :(得分:4)

你的版本必须不稳定。 :-P在OpenJDK上测试时(与Ubuntu 9.10一起分发),这就是我得到的:

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

基于OP编辑的更新:Eclipse使用自己的Java编译器,称为ecj;它不使用JDK编译器(javac)。这就是为什么你有时会得到不同的输出。 (是的,生成的字节码有时也不同,导致时髦differences in behaviour,具体取决于您是否在Eclipse中编译了代码。)

(另外,根据我的经验,ecjjavac之间的另一个区别是:javac会告诉您如果您的字符串常量超过65535字节,则会丢失(这是类文件格式的限制)。ecj实际上会尝试模拟这样一个长字符串常量,通过拼凑较短的部分,每个拟合在64k限制内,使用StringBuilder,然后最终实习结果---就像“真正的”字符串常量一样。)

答案 1 :(得分:3)

Java编译器消息通常非常无用。它们只对编译器编写者有意义。

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

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