Подтвердить что ты не робот

Пустые утверждения if

В "пустой if-statement" я имею в виду что-то вроде этого (обратите внимание на точку с запятой):

if (condition);

У меня возникли проблемы с приложением приложения для этого. С циклом while вы можете сделать это:

while (callUntilReturnsFalse());

Но нет такого приложения для if-statement. Что еще, компилятор Java не выдаёт ошибку или предупреждение при столкновении с таким выражением. Это может привести к большим и бесшумным проблемам, особенно с длинным и запутанным утверждением:

if ((functionA() && functionB(getFoo()) ||
    checkForComplexCondition(arg1, arg2, getBar(getFoo())));
{
    doStuff();
}

Мой вопрос: почему это разрешено в Java? И, что еще более важно, могу ли я включить опцию вызывать предупреждение, когда это произойдет?

(Этот вопрос был перед в отношении С#, который вызывает предупреждение, но я надеялся найти способ вызвать предупреждение с помощью Java.)

4b9b3361

Ответ 1

почему это разрешено в Java?

См. Спецификация языка Java (14.6. Пустое выражение):

Пустая инструкция ничего не делает.

Это просто разрешено и эквивалентно (и будет переведено):

if (condition) {  }

Это означает, что если условие истинно, ничего не делать.

Если вы используете eclipse, вы можете посмотреть здесь, вы можете найти что-то полезное (я не уверен, что существует такая опция для терминатора с точкой с запятой):

Окно → Настройки → Java → Компилятор → Ошибка/предупреждения

enter image description here


ИЗМЕНИТЬ

Как отметил @nullptr в своем ответе, для этого есть предупреждение IDE, вам нужно установить предупреждение в оператор Empty.

Ответ 2

Я не думаю, что это действительно актуально для намерения вопроса, но я думаю, что это должно быть указано, поскольку оно имеет отношение к сути вопроса.

Там есть эффект:

if(variable);

если переменная volatile. Это означает, что барьер памяти должен выполняться между текущим потоком и любыми другими потоками, обращающимися к переменной.

public volatile variable;
....
if(variable);

Подробнее см. здесь.

Я не могу себе представить какую-либо реальную ценность для того, чтобы помещать этот вид заявления в ваш код, но я счел важным отметить, что это реальное влияние на этот оператор в этой конкретной ситуации.

Ответ 3

Есть одна конструкция, которую я использую довольно часто, что "нулевой оператор" становится понятным и понятным. Вот пример:

for (int i=0;  i < argc;  i++)
{
   if (argv[i]=="left")
      hpos++;
   else if (argv[i]=="right")
      hpos--;
   else if (argv[i]=="up")
      ;
   else if (arv[i]=="down")
      ;
   else fprintf(stderr, "Unknown option \"%s\\n".", argv[i]);
}

В этом случае я все же хочу проверить наличие существования определенных опций, а только выполнить код для some из них. В этом случае использование нулевого оператора, как указано выше, делает функцию и структуру кода более читабельными и понятными для следующего парня, который должен прийти и поддерживать его.

Конечно, есть способы реструктурировать этот код, чтобы не требовать нулевой оператор. Но я не верю, что его намерение будет таким же ясным, как в фрагменте кода.

Ответ 4

Я не вижу такой опасности в возможности if с пустой инструкцией. Обоснование этого лежит в грамматике языка Java, что позволяет использовать пустой оператор ;:

Block: 
    { BlockStatements }

BlockStatements: 
    { BlockStatement }

BlockStatement:
    LocalVariableDeclarationStatement
    ClassOrInterfaceDeclaration
    [Identifier :] Statement

LocalVariableDeclarationStatement:
    { VariableModifier }  Type VariableDeclarators ;

Statement:
    Block
    ;
    Identifier : Statement
    StatementExpression ;
    if ParExpression Statement [else Statement] 
    assert Expression [: Expression] ;
    switch ParExpression { SwitchBlockStatementGroups } 
    while ParExpression Statement
    do Statement while ParExpression ;
    for ( ForControl ) Statement
    break [Identifier] ;
    continue [Identifier] ;
    return [Expression] ;
    throw Expression ;
    synchronized ParExpression Block
    try Block (Catches | [Catches] Finally)
    try ResourceSpecification Block [Catches] [Finally]

Помните, что это верно для почти всех императивных языков.

Я имею в виду, что это может быть опасно и трудно найти как любое другое пустое тело, если вы забыли какую-либо реализацию, конечно, я бы не потерял сон. В длинном и запутанном заявлении вы можете получить проблемы из-за того, что ( ) закрывает неправильную пару выражений или даже неправильно думает о вашем состоянии (особенно со многими && и ||).

Ответ 5

Я нашел предупреждение для этого в Eclipse как Empty statement:

example

Спасибо Маруну Маруну за то, что он поставил меня на правильный путь.

Ответ 6

Я в основном разработчик С#, хотя у меня есть немного фона Java. Но я думаю, что мой ответ относится к обоим. Я подозреваю, что это не преднамеренная функция, а скорее возникшая особенность. Грамматика языка идет (примерно)

if (*condition*)
    *statement*

К сожалению, нижеследующие являются действительными операторами (я проверял, вы можете удалить столько же на С#, сколько хотите, и компилятор не жалуется):

;

{
}

Поэтому конструкция, которую вы выделили, разрешена.

Ответ 7

Условие может быть вызовом функции с побочными эффектами. Было бы неправильным рассматривать это как ошибку или предупреждение.

Ответ 8

В заявлении

if  (eval) { //pseudo-code
}

Иногда данные фактически изменяются при оценке (eval). Например, в

while (someIterator.next()) {
}

Вызов next() фактически изменяет состояние объекта someIterator.

И, конечно, есть классический пример, который обычно происходит из-за опечатки (и не рекомендуется)

int x;  
if (x = getNumberOfWidgets() > 5) {
}

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

Ответ 9

Я считаю, что они оставили его, потому что он может повысить удобочитаемость кода. Даже если ничего не нужно делать для случая, вы все равно можете сообщить людям, что дело важно.

Ответ 10

Большинство компиляторов Java вообще не оптимизируют код. Они делегируют эту работу во время выполнения в среду выполнения Java Runtime. JVM проверяет код перед его выполнением, , но эта проверка состоит (в основном) из трех проверок:

  • Вложения в действительных позициях (не совпадают с правильными).
  • Данные всегда инициализируются, и ссылки всегда безопасны для текста.
  • Доступ к личным данным контролируется.

Итак, ваш оператор if может быть неправильным, но он все еще действителен. Действуя как

 if (a==a)