«Левая часть присваивания должна быть переменной» из-за лишних скобок - PullRequest
2 голосов
/ 24 марта 2010

Я знаю, почему следующий код не компилируется:

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) жалуется на то, что «левая часть назначения должна быть переменной».

Я бы ожидал что-то вроде "Не ставьте скобки вокруг вызова метода, пустышка!", Вместо этого.

Так почему же компилятор делает совершенно бесполезную жалобу на что-то явно неуместное?

Является ли это результатом неясности в грамматике? Баг в компиляторе?

Если это первое, не могли бы вы спроектировать язык так, чтобы компилятор никогда не был настолько неосновным в отношении синтаксической ошибки, подобной этой?


Хорошо, я только что проверил, и, по-видимому, эта жалоба видна только из Затмения. Если я компилирую из командной строки, это дает более заметную ошибку «Не утверждение». Тайна углубляется.

Ответы [ 2 ]

4 голосов
/ 24 марта 2010

Ваша версия должна быть шаткой. :-P При тестировании на OpenJDK (как распространяется с Ubuntu 9.10), это то, что я получаю:

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

Обновление на основе редактирования OP: Eclipse использует собственный Java-компилятор, который называется ecj; он не использует JDK-компилятор (javac). Вот почему вы иногда получаете разные результаты. (И да, сгенерированный байт-код тоже иногда отличается, вызывая различие в поведении в зависимости от того, скомпилировали ли вы свой код в Eclipse.)

(Кроме того, другое отличие между ecj и javac в моем опыте: javac скажет вам потеряться, если у вас есть строковая константа длиной более 65535 байт (это ограничение в файле класса формат). ecj на самом деле будет пытаться эмулировать такую ​​длинную строковую константу, объединяя более короткие части, каждая подгонка в пределах предела 64k, с StringBuilder, а затем, наконец, интернируя результат - точно так же, как это было бы с "настоящая" строковая константа.)

3 голосов
/ 24 марта 2010

Сообщения компилятора Java, как правило, очень бесполезны. Они действительно имеют смысл только для авторов компиляторов.

С точки зрения синтаксического анализатора, он получает выражение и доходит до того, что единственное, что остается сделать - назначить его переменной, а его нет, поэтому он сдается.

Не могли бы вы разработать более полезные сообщения компилятора? Я полагаю, но я сомневаюсь, что Sun / Oracle считает это высоким приоритетом.

...