Как переписать условие if без скобок, чтобы избежать ошибок?
Что проверяют
Видите ли вы, какие ошибки провоцирует if без фигурных скобок, и знаете ли, как команда защищается от них не силой воли, а инструментами. Часто дают фрагмент с вложенными if и одним else и просят сказать, к какому условию он относится.
Как отвечать
Короткий ответ: всегда ставить фигурные скобки, даже вокруг одной строки. Дальше покажите, от чего это защищает:
- добавленная строка: к
if (x) a();дописываютb();с тем же отступом, иb()выполняется всегда. Отступы компилятор не читает, теломifостаётся только первая инструкция. Так появилась известная уязвимостьgoto failв проверке TLS: продублированная строка без скобок пропускала проверку подписи; - висячий
else:elseотносится к ближайшемуifбез пары, как бы ни стояли отступы. Во вложенных условиях без скобок логика легко оказывается не той, что задумана; - лишняя точка с запятой:
if (x); { a(); }компилируется, пустая инструкция становится телом, а блок выполняется всегда.
Правило закрепляют инструментами. В Google Java Style скобки обязательны даже для одной инструкции, Checkstyle проверяет это правилом NeedBraces, в IntelliJ IDEA есть настройка Code Style с принудительными скобками, которую применяет Reformat Code.
Помимо скобок условия упрощают структурно: ранний возврат (guard clause) вместо глубокой вложенности, switch-выражение со стрелками вместо цепочки else if, тернарный оператор только для выбора значения, а не для побочных эффектов.
Где спотыкаются
Отвечают «скобки лишние, если строка одна», не называя ни одного реального бага. Интервьюер ждёт как раз сценарии поломки.
Заменяют всё тернарными операторами. Вложенный тернарник читается хуже любого if, а cond ? 1 : map.get(k) при null в словаре бросит NullPointerException из-за распаковки.
Путают сравнение с присваиванием: if (flag = true) для boolean компилируется и всегда истинно. Сравнивать логическую переменную с литералом вообще не нужно, достаточно if (flag).