Синтаксическая ошибка в двойном токене в теле оператора if

Когда я пытаюсь запустить этот код:

public static void main(String[] args) {

    double salary = 10.1;

    if (salary >= 100.3)
        double number = salary * 10;
    else
        double number = salary * 20;

}

Я получаю следующие ошибки:

Синтаксическая ошибка в токене "двойной", удалите этот токен

и то и другое:

число не может быть преобразовано в переменную

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

Насколько я понимаю, лучше всего не объявлять одну и ту же переменную дважды и лучше всегда использовать фигурные скобки; но почему double number = salary * 10; и double number = salary * 20; вызывают проблему, если фигурные скобки не используются? Я бы подумал, что это все равно будет правильно компилироваться и работать (это работает, если используются скобки).


person Community    schedule 14.01.2018    source источник
comment
Объявление не допускается в операторе if без фигурных скобок. Это потому, что если у вас может быть только один оператор в if, объявление бесполезно. Объем заканчивается немедленно.   -  person bcsb1001    schedule 14.01.2018
comment
Прочтите это: stackoverflow.com/questions/38766891/   -  person GalAbra    schedule 14.01.2018
comment
Можно, конечно, сделать double number = salary >= 100.3 ? salary * 10 : salary * 20; или даже double number = salary * (salary >= 100.3 ? 10 : 20);   -  person T.J. Crowder    schedule 14.01.2018
comment
@ bcsb1001 это было бы не совсем бесполезно: int a = someFunctionWithSideEffect(a = veryExpensiveMethod(), a); является (в противном случае) законным (возможно, неожиданно); здесь a можно использовать как временную переменную, чтобы избежать повторного вычисления параметра. Но это не совсем разумный код, и если вы действительно хотите его использовать, вы всегда можете просто заключить его в фигурные скобки. Просто указываю, что вы можете использовать объявление переменной в if для какой-то смутно практической цели.   -  person Andy Turner    schedule 14.01.2018


Ответы (1)


Потому что это нарушает грамматику Java. JLS определяет if операторов следующим образом:

IfThenStatement:
    if ( Expression ) Statement

Итак, ожидается Statement. Фигурные скобки обозначают Block и Block является Statement. Однако объявление переменной не является Statement.1

Это интуитивно разумное поведение — если бы вы могли объявить здесь переменную, это было бы бесполезно, так как сразу же вышло бы за пределы области видимости.


1. Как ни странно, объявления переменных называются LocalVariableDeclarationStatements в JLS. Однако это не Statement в том, что касается языковой грамматики.

person Oliver Charlesworth    schedule 14.01.2018
comment
В каком смысле они не являются заявлением? Конечно, они не Statement, но они BlockStatement. - person Andy Turner; 14.01.2018
comment
@AndyTurner - Может быть, форматирование моего ответа поможет? BlockStatement не является Statement, а if ожидает Statement. - person Oliver Charlesworth; 14.01.2018
comment
да, я думаю, что обратные кавычки сделали бы это более понятным. Я думаю, что сбивает с толку то, что спецификация называет это Statement, хотя другие типы операторов не включены в это. - person Andy Turner; 14.01.2018