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

Точка с запятой в конце выражения "if"

Сегодня, после получаса поиска ошибки, я обнаружил, что можно ставить точку с запятой после оператора if вместо кода, например:

if(a == b);
// Do stuff

Что в основном означает, что все будет выполнено независимо a равен ли b или нет, и оператор if не имеет никакого смысла. Почему Java не дает мне ошибку? Есть ли ситуации, в которых это было бы полезно?

4b9b3361

Ответ 1

Почему это происходит?

Спецификация Java Language говорит, что:

Пустое выражение

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

EmptyStatement:
    ;

Выполнение пустой инструкции всегда выполняется нормально

Это по сути означает, что вы хотите выполнить пустой оператор, если a == b

if(a == b);

Что делать:

Существует два основных решения этой проблемы:

  • Вы можете избежать проблем с пустой инструкцией с помощью форматирования кода и окружающие вещи внутри if с помощью { и }. Делая это Ваш пустой оператор будет более читабельным.

    if(a == b){
      ;
    }
    
  • Вы также можете проверить инструменты, используемые для анализа статического кода, например:

    Они могут мгновенно выделять такие проблемы, как этот.

Я бы рекомендовал объединить оба решения.

Ответ 2

Есть ли какая-нибудь ситуация, в которой это было бы полезно?

Полезно? Как в разделе "делает ваш код более чистым, понятным, быстрым, более удобным"? Не за что. Это, скорее всего, плохой, запутанный код.

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

if( a() && b() );

Здесь a() или b() может что-то сделать, а b() будет выполняться, только если a() - true.

Что касается того, почему, я думаю, ответ просто заключается в том, что было бы хуже отклоняться от определенного ожидаемого поведения (например, таких утверждений, как while(reader.read());), чем альтернатива разработчикам, которые пишут плохой код.

Написание плохого кода всегда возможно. И просто повторить, это будет плохой код практически в любом случае.

Ответ 3

Возможный прецедент:

if (a==b);
else {
  // Do something
}

Нехорошо, но возможно.

Тем не менее, я считаю, что спецификация Java должна запрещать пустой if.

Ответ 4

Если вы используете Eclipse, вы можете предупредить вас об этих утверждениях:

Java->Compiler->Errors/Warnings

Ответ 5

Если вы используете оператор if, первый оператор после if будет выполнен, если условие истинно. Если у вас есть блок после if (с фигурными фигурными скобками), он рассчитывает на весь этот блок. Если нет блока, он учитывает только один оператор. Единая точка с запятой - это пустой оператор. Вы также можете написать код из примера:

if(a==b) {
    ;
}

Ответ 6

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

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

В списке элементов Java использует явное ключевое слово null, но "нулевой оператор" - это просто пустая строка. Разрешение существования пустой строки - это удержание из традиции, унаследованной от C.

Зачем? Особенно с выражением if, когда вы знаете, что никакие утверждения не выполняются: поскольку некоторые операторы if имеют побочные эффекты:

 int c;
 if ((c = in.read()) != -1);

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

Ответ 7

Я не могу придумать, где это полезно. Это может быть полезно для таких циклов, как

 while(do something);

или

 for(init; do something; something else);

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

Ответ 8

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

Ответ 9

Почему? Это потому, что проще для компиляторов. Вам не нужно делать специальный случай для проверки точки с запятой после if(cond) и имеет дополнительное использование разрешений

if (cond && maybeFunc())
    ;// Code here I want to ignore

Несмотря на то, что это действительно страшная идея разрешить это. Это просто проще разрешить, а затем добавить случай, чтобы проверить это.

Ответ 10

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

Я согласен, что это прежде всего причина ошибок, которые сложно найти. Я всегда использую фигурные скобки вокруг блоков, даже если есть один оператор, но Java позволяет вам сделать блок с фигурными скобками в любой момент, поэтому использование фигурных скобок не может спасти вас от этой участи. Например, я однажды потратил 4 часа на то, чтобы найти что-то вроде этого:

while (condition);
{
    statement;
    statement;
}

Точка с запятой в конце первой строки была опечаткой, случайно сделав блок оператора для цикла while пустым. Поскольку синтаксис действителен, программа скомпилирована и работает нормально, просто не так, как я этого хотел. Это было действительно трудно найти.

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

if (condition1) {
    do_action_1();
}
else if (condition2) {
    //nothing really to do in this case
}
else if (condition3) {
    do_action2();
}
else {
    do_action3();
}

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

Я лично предпочел бы явный оператор noop, но это не так, как определяется Java.

Ответ 11

Просто FYI о юзабилити и , какую разницу он делает или может сделать, если есть такой оператор

Рассмотрим фрагмент кода, как показано ниже.

int a = 10;
if ((a = 50) == 50);

System.out.println("Value of a = " + a);

Очевидно, что в этом случае оператор if изменяет вывод. Таким образом, подобное выражение может иметь значение.

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

Ответ 12

if(a==b)
    println("a equals b");

Вы можете использовать оператор IF без {}, если есть только одна строка, которая должна быть выполнена, поэтому, используя if(a==b);, вы говорите, если они равны, выполняют и пустую инструкцию... Поэтому он ничего не сделает, а затем вернитесь к своему нормальному циклу вне блока IF.

Ответ 13

Несколько определений из jls объясняют это (глава 14):

Блоки - это выражения

Как указано здесь, a Block является StatementWithoutTrailingSubstatement, который, в свою очередь, является StatementNoShortIf, который является Statement. Таким образом, когда требуется какое-либо из них, мы можем вставить Block.

Предложение if

Хотя это также относится к for и while -loops, я буду использовать if -statements. Эти правила почти одинаковы. Синтаксическое описание if-statements можно найти здесь здесь.

IfThenStatement:
    if ( Expression ) Statement

IfThenElseStatement:
    if ( Expression ) StatementNoShortIf else Statement

IfThenElseStatementNoShortIf:
    if ( Expression ) StatementNoShortIf else StatementNoShortIf

Итак, мы можем использовать наш блок здесь.

Но с чем это связано?

; определяется как EmptyStatement (ссылка), что также равно StatementNoShortIf. Таким образом, в условных фрагментах кода, таких как if-statement и циклы, мы можем заменить Block на EmptyStatement, если требуется StatementNoShortIf или Statement.

Таким образом, if(Expression)EmptyStatement работает.

Почему это не дает ошибку?

Довольно просто: java дает ошибку, если находит недопустимый синтаксис. Но if(Expression)EmptyStatement - вполне допустимый синтаксис. Вместо этого javac выдает предупреждение, если запускается с соответствующими параметрами. полный список предупреждений, которые могут быть отключены, для этой цели содержит имя-предупреждение empty. Таким образом, компиляция с помощью -Xlint:all или -Xlint:empty генерирует предупреждение об этом.

В вашей среде IDE также должна быть возможность включить этот вид предупреждения. Для eclipse см. @nullptr answer. В IntelliJ вы можете нажать Ctrl + Shift + A, ввести empty body в поле поиска и включить предупреждение (помеченное на изображении)

IntelliJ включить предупреждение о пустое тело

Что это даже используется для?

Честно говоря, в нем мало пользы с минималистской точки зрения. Обычно есть способ добиться успеха без команды "ничего не делать". Это скорее вопрос личных предпочтений, предпочитаете ли вы использовать

if( a() && b() );

или

if( a() ) b();

и это применимо и к другим случаям, в которых используется EmptyStatement. Важным моментом для рассмотрения этой темы является читаемость кода. Бывают случаи, когда код становится более читаемым, используя no-op. С другой стороны, есть случаи, когда код становится намного сложнее понять с помощью EmptyStatement - приведенный выше пример будет рассчитывать на более позднюю IMO.

Ответ 14

Точка с запятой в конце,
если (а == Ь); просто закончить оператор в одной строке, что означает игнорировать результат условия и продолжить выполнение из следующей строки
Этот код полезен, с другой стороны, иногда вводит ошибку в программе, например,
 
case 1.

 a = 5;
 b = 3,
 if (a == b);
prinf ( "a и b равны" ),
Случай
2.

 a = 5;
 b = 5;
 if (a == b);
prinf ( "a и b равны" ),
будет печатать тот же результат на экране...

Ответ 15

Я могу думать о сценарии, где требуется пустой оператор (не для условия if, а для цикла while).

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

    System.out.println("Enter Y to proceed. Waiting...");
    System.out.println("");

    while(!(new Scanner(System.in).next().equalsIgnoreCase("Y")));

    System.out.println("Proceeding...");
    // do the work here

Ответ 16

посмотри это:

int a,b,c = 0;
if(a == b){
   c =1;
} 
System.out.print(c);//1

Итак, вы можете написать так:

if (a == b)c=1;

но, если этот код такой:

int a,b,c=0;
if (a != b){
}
if (a == b ){
  c =1;
}

Вы можете написать так:

if(a != b);
if(a == b )c=1;

Итак, вы будете знать, if(a != b); отмечать

Ответ 17

Точка с запятой в if указывает на завершение условия if, как в java ; трактуется как конец оператора и оператор после if выполняется.

Ответ 18

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

if (row == 0); 
else (method (grid[row][col], grid[row-1][col]));
if (row == N-1);
else (method (grid[row][col], grid[row+1][col]));
if (col == 0);
else (method (grid[row][col], grid[row][col-1]));
if (col == N-1);<br>
else (method (grid[row][col], grid[row][col+1]));

где method(Doodad a, Doodad b) выполняет некоторую операцию между a и b.

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