Условный оператор if выполняет блок кода, только если выражение в скобках равно true (JLS, раздел 14.9). Такое выражение собирают из операторов сравнения (>, >=, <, <=, ==, !=) и логических операторов !, &&, ||. Ниже разбор всех трех групп, формы if, if-else и else if, тернарный оператор и пять типичных ошибок новичков.

Кратко

  • Условие в if всегда имеет тип boolean: число туда подставить нельзя, if (1) это ошибка компиляции.
  • Логические операторы: ! переворачивает значение, && требует истинности обоих условий, || хотя бы одного.
  • Приоритет: сначала арифметика, потом сравнения, затем !, && и || в таком порядке, а присваивание в самом конце. Сомневаешься, ставь скобки.
  • Короткое замыкание: && не вычисляет правый операнд, если левый уже false, а || если левый уже true. На этом строят проверки вида str != null && str.isEmpty().
  • Форм три: if, if-else и цепочка else if. Java идет по цепочке сверху вниз и останавливается на первом истинном условии.
  • Тернарный оператор условие ? a : b это сокращенный if-else, который возвращает значение. Годится для простого выбора из двух вариантов.
Знаешь, что общего у светофора, банкомата и твоего любимого мобильного приложения? Все они постоянно принимают решения. "Если карта действительна, выдай деньги", "если здоровье персонажа на нуле, конец игры", "если пользователь ввел правильный пароль, пусти его в систему". Вот честно, первые пару недель обучения программированию я писал код, который просто выполнялся строчка за строчкой. Сверху вниз. И все. Скучно до невозможности! А потом узнал про условные операторы, и мир программирования сразу стал другим. Программа вдруг начала что-то решать сама! Без условий ты максимум сделаешь калькулятор. Ну или программу "Hello World" в десяти вариациях. А вот игры, мессенджеры, любые сервисы: там без if никуда. Давай разберемся, как это работает в Java.Разноцветные конверты и карандаш на синем фоне, на карточках надписи условный оператор if и логические операторы

Логические операторы: штука без которой условия не построишь

Окей, сначала нужно понять базу. Прежде чем писать условия, тебе понадобятся логические операторы. Это такие инструменты, которые позволяют комбинировать проверки. Звучит сложно? Сейчас объясню.

Три кита: И, ИЛИ, НЕ

В Java есть три основных логических оператора. Запомнить легко, потому что логика у них простая: Оператор ! (восклицательный знак) это "НЕ". Переворачивает все с ног на голову. Было true, стало false. И наоборот. Допустим, у тебя переменная isRaining (идет дождь). Пишешь !isRaining и получаешь "НЕ идет дождь". Элементарно. Оператор && (два амперсанда) это логическое "И". Работает строго: оба условия должны быть истинными, иначе результат false. Представь охранника в клубе, которому нужно предъявить И билет, И паспорт с возрастом 18+. Не хватает одного из документов? Извини, братан, проходи мимо. Оператор || (две вертикальные черты) это логическое "ИЛИ". Тут попроще: хватит одного истинного условия. Как акция в магазине: "скидка действует, если у вас карта лояльности ИЛИ день рождения в этом месяце". Достаточно чего-то одного. Смотри пример:

boolean hasTicket = true;
boolean isAdult = false;

// Отрицание
boolean isChild = !isAdult; // true, потому что не взрослый

// Логическое И: нужны ОБА условия
boolean canEnterClub = hasTicket && isAdult; // false (билет есть, но возраст не тот)

// Логическое ИЛИ: хватит одного  
boolean canGetDiscount = isChild || hasTicket; // true

System.out.println("Пустят в клуб: " + canEnterClub); // false
System.out.println("Скидка положена: " + canGetDiscount); // true
Вот и вся магия.

Приоритет операторов (да, и тут своя очередность)

Ладно, допустим, ты напишешь что-то вроде a || b && !c. Что выполнится первым? Компьютер же не экстрасенс, чтобы угадывать твои мысли. Поэтому в Java есть четкие правила: Первым делом работает отрицание !. Потом идет && (логическое И). И только в конце || (логическое ИЛИ). Запомнить можно по аналогии с математикой: там же сначала умножение и деление, а потом сложение и вычитание. Тут похожий принцип. Не уверен в порядке? Ставь скобки. Серьезно, это спасает от множества багов. Скобки всегда в приоритете:

boolean a = true;
boolean b = false;
boolean c = true;

// Без скобок: ! выполнится первым, потом &&, потом ||
boolean result1 = a || b && !c; // получится true

// Со скобками меняем всю логику
boolean result2 = (a || b) && !c; // получится false

System.out.println("Без скобок: " + result1);    // true
System.out.println("Со скобками: " + result2);   // false
Видишь разницу? Одни скобки, и результат другой.

Фишка с ленивыми вычислениями (короткое замыкание)

А вот теперь интересное. Java достаточно умная, чтобы иногда… схалтуривать. В хорошем смысле! Смотри: если у тебя условие с оператором &&, и первая часть уже false, зачем проверять вторую? Результат и так будет false. Java так и делает: пропускает вторую проверку. Это называется "коротким замыканием" или short-circuit evaluation. То же самое с ||: если первое условие true, второе даже не смотрит. В спецификации языка это описано прямо: правый операнд вычисляется, только если левый оказался нужного значения. Пример из жизни:

int balance = 100;
int amount = 500;

// Java проверит balance > 0, увидит true
// и дальше даже не пойдет! Деления на ноль не будет
if (balance > 0 || amount / 0 > 100) {
    System.out.println("Этот код спокойно выполнится");
}

// А вот тут будет беда: первое условие true,
// и Java пойдет проверять второе... привет, деление на ноль!
if (balance > 0 && amount / 0 > 100) {
    System.out.println("До сюда не дойдет: будет ошибка");
}
Кстати, есть еще & и | (без удвоения): они всегда проверяют оба условия. Но в реальных проектах их почти никто не использует для логики. Зачем делать лишнюю работу, если можно не делать?

Операторы сравнения: больше, меньше и все такое

Теперь про операторы сравнения. Тут все проще: обычная школьная математика, только в коде. У нас есть шесть штук: > это больше >= это больше или равно < это меньше <= это меньше или равно == это равно (внимание: два знака равенства!) != это не равно Все они берут два значения (чаще всего числа), сравнивают их и возвращают boolean: либо true, либо false.

int playerHealth = 75;
int maxHealth = 100;
int dangerZone = 30;

boolean isFullHealth = playerHealth == maxHealth;     // false
boolean isDangerous = playerHealth < dangerZone;      // false  
boolean needsHealing = playerHealth <= 50;            // false
boolean isAlive = playerHealth > 0;                   // true
boolean isDamaged = playerHealth != maxHealth;        // true

System.out.println("Здоровье полное: " + isFullHealth);  // false
System.out.println("Нужно лечиться: " + needsHealing);   // false
System.out.println("Персонаж ранен: " + isDamaged);      // true
Частая ошибка новичков: путать == (сравнение) с = (присваивание). Я сам в первые недели постоянно на этом спотыкался!

int score = 100;           // Присваивание: записали 100 в переменную
boolean isWin = score == 100;  // Сравнение: проверяем, равен ли score 100
Один знак равенства это присваивание. Два знака это сравнение. Запомни раз и навсегда.

Приоритет: что считается первым

Когда в одном выражении куча разных операторов, Java выполняет их в определенном порядке. Сначала арифметика (плюсы-минусы), потом сравнения, потом логические операции, и только в конце присваивание.

int a = 5;
int b = 3;

// Порядок: 5 + 3 = 8, потом 8 > 7, потом результат в переменную
boolean result = a + b > 7; // true

System.out.println(result); // true
В общем-то, интуитивно понятно. Но если сомневаешься, всегда можно скобками явно указать порядок.

Шпаргалка по операторам

Соберем все операторы из этой статьи в одну таблицу, чтобы было куда подглядывать:
Оператор Что делает Пример Результат
> больше 7 > 5 true
>= больше или равно 5 >= 5 true
< меньше 7 < 5 false
<= меньше или равно 7 <= 5 false
== равно (для чисел и boolean; для строк нужен equals()) 5 == 5 true
!= не равно 5 != 5 false
! НЕ, меняет значение на противоположное !true false
&& И, истинно только если оба операнда истинны; правый не вычисляется, если левый false true && false false
|| ИЛИ, истинно если истинен хотя бы один; правый не вычисляется, если левый true true || false true
& и | то же И и ИЛИ, но без короткого замыкания: оба операнда вычисляются всегда false & проверка() false, но проверка() вызовется

Условный оператор if: наконец-то учим программу думать

Окей, теперь самое главное: оператор if. Это основа основ. С его помощью программа начинает вести себя по-разному в зависимости от ситуации.

Простейшая форма if

Синтаксис элементарный:

if (условие) {
    // этот код выполнится, если условие true
}
Условие в скобках возвращает boolean. Если true, код внутри фигурных скобок выполнится. Если false, Java просто пропустит этот блок и пойдет дальше. Живой пример:

int age = 20;

if (age >= 18) {
    System.out.println("Добро пожаловать!");
}

// Если возраст меньше 18, программа просто ничего не выведет
Технически фигурные скобки можно не ставить, если внутри всего одна команда:

int money = 1000;

if (money > 0) 
    System.out.println("Есть деньги на счету");
Но знаешь что? Не делай так. Потом захочешь добавить еще одну строчку кода, забудешь про скобки и получишь баг, который будет искать полдня. Лучше всегда пиши фигурные скобки. Поверь, так спокойнее.

if-else: или то, или другое

Часто нужно сделать что-то одно, если условие выполнено, и что-то другое, если нет. Для этого придумали else:

if (условие) {
    // сюда, если true
} else {
    // сюда, если false
}
Классика, проверка перед делением на ноль:

int dividend = 100;
int divisor = 0;

if (divisor != 0) {
    int result = dividend / divisor;
    System.out.println("Результат: " + result);
} else {
    System.out.println("На ноль делить нельзя!");
}
Или проверяем четность числа:

int number = 7;

if (number % 2 == 0) {
    System.out.println(number + " это четное");
} else {
    System.out.println(number + " это нечетное");
}
// Выведет: 7 это нечетное
Просто и понятно.

else if: когда вариантов больше двух

Жизнь редко бывает черно-белой. Обычно есть куча вариантов. Вот для этого придумали else if: можно проверить несколько условий подряд:

if (условие1) {
    // если условие1 истинно
} else if (условие2) {
    // если условие1 ложно, а условие2 истинно
} else if (условие3) {
    // если первые два ложны, а условие3 истинно
} else {
    // если вообще ничего не подошло
}
Java идет сверху вниз и останавливается на первом истинном условии. Остальные даже не проверяет. Реальный пример, система оценок:

int score = 85;

if (score >= 90) {
    System.out.println("Оценка: A (Отлично!)");
} else if (score >= 80) {
    System.out.println("Оценка: B (Хорошо)");
} else if (score >= 70) {
    System.out.println("Оценка: C (Удовлетворительно)");
} else if (score >= 60) {
    System.out.println("Оценка: D (Слабовато)");
} else {
    System.out.println("Оценка: F (Эх...)");
}
// Выведет: Оценка: B (Хорошо)
Или игровая механика:

int level = 15;
String difficulty;

if (level < 5) {
    difficulty = "Новичок";
} else if (level < 10) {
    difficulty = "Любитель";
} else if (level < 20) {
    difficulty = "Профи";
} else {
    difficulty = "Бог войны";
}

System.out.println("Сложность: " + difficulty);
// Выведет: Сложность: Профи
Удобно же?

Проверка типа: instanceof с переменной

Отдельный вид условия это проверка типа. Раньше после instanceof приходилось вручную приводить объект:

if (obj instanceof String) {
    String text = (String) obj;   // лишняя строка
    System.out.println(text.length());
}
С Java 16 (JEP 394) переменную объявляют прямо в условии, и приведение делает компилятор:

if (obj instanceof String text) {
    System.out.println(text.length());
}
Переменная text видна внутри блока и в остальной части условия, поэтому можно сразу писать if (obj instanceof String text && !text.isEmpty()).

Вложенные if: когда надо проверить что-то внутри проверки

Иногда нужна проверка внутри проверки. Типа, сначала проверяем возраст, а потом есть ли права:

int age = 25;
boolean hasLicense = true;

if (age >= 18) {
    if (hasLicense) {
        System.out.println("Можете арендовать авто");
    } else {
        System.out.println("Сначала получите права");
    }
} else {
    System.out.println("Слишком молоды");
}
Работает, но злоупотреблять не стоит. Если вложенность больше 2-3 уровней, код превращается в кашу. Лучше объединить условия через &&:

// Плохо: куча вложенных if
if (isOnline) {
    if (hasPermission) {
        if (dataValid) {
            if (networkOk) {
                // делаем что-то
            }
        }
    }
}

// Хорошо: объединили все в одно условие
if (isOnline && hasPermission && dataValid && networkOk) {
    // делаем что-то
}
Второй вариант читается проще. Всегда думай о том, кто будет читать твой код потом (спойлер: это, скорее всего, будешь ты же через три месяца).

Тернарный оператор: if в одну строчку

Есть еще один способ писать условия: тернарный оператор ? :. Это как сокращенный if-else, только возвращает значение:

переменная = условие ? значениеЕслиTrue : значениеЕслиFalse;
Пример:

int age = 20;
String status = age >= 18 ? "Взрослый" : "Ребенок";
System.out.println(status); // Взрослый
Это абсолютно то же самое, что:

int age = 20;
String status;
if (age >= 18) {
    status = "Взрослый";
} else {
    status = "Ребенок";
}
System.out.println(status); // Взрослый
Только короче. Удобно для простых случаев:

int a = 10;
int b = 20;
int max = a > b ? a : b; // max = 20

int price = 1000;
int discount = price > 500 ? 100 : 50; // скидка 100
Но не увлекайся! Если логика сложная, лучше обычный if. Никому не нравится разбираться в тернарниках типа:

// Ужас, не делай так
String result = a > b ? (c > d ? "вариант1" : "вариант2") : (e > f ? "вариант3" : "вариант4");
Такое даже читать больно. Используй тернарник только для простых выборов из двух значений.

Ошибки, на которых все спотыкаются (и ты тоже споткнешься)

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

1. Перепутал = и ==

Классика жанра. Одинарный знак равенства это присваивание. Двойной это сравнение.

int x = 5;

// Так НЕ работает! Это попытка присвоить, а не сравнить
if (x = 10) { // Ошибка компиляции
    System.out.println("x равен 10");
}

// А вот так правильно
if (x == 10) {
    System.out.println("x равен 10");
}
Я первую неделю путал постоянно. Потом выработался рефлекс.

2. Сравнивал строки через ==

Это вообще коварная штука. Иногда работает, иногда нет. Для строк нужен метод .equals():

String name1 = "Максим";
String name2 = new String("Максим"); // например, имя пришло из файла или из сети

// Плохо! Тут сравниваются ссылки, а не содержимое
if (name1 == name2) { 
    // Этот блок не выполнится: объекты разные
}

// Правильно
if (name1.equals(name2)) {
    System.out.println("Имена одинаковые");
}
Запомни: для строк всегда .equals(). Для чисел и boolean можно ==. Кстати, если бы обе переменные были объявлены одинаковыми литералами, == вернул бы true: литералы берутся из общего пула строк. Именно поэтому ошибка и коварная, на маленьких примерах она не проявляется.

3. Забыл фигурные скобки

Пропустил скобки, думая что в условии одна строка. А там оказалось две. Результат это баг.

int score = 80;

// Опасно! Вторая строка НЕ в условии
if (score > 50)
    System.out.println("Тест пройден");
    System.out.println("Поздравляем!"); // Выполнится ВСЕГДА!

// Правильно
if (score > 50) {
    System.out.println("Тест пройден");
    System.out.println("Поздравляем!");
}
Совет: всегда ставь фигурные скобки. Всегда. Даже если там одна строка.

4. Проверял boolean через == true

Лишние проверки. Переменная и так boolean, зачем ее с true сравнивать?

boolean isActive = true;

// Неправильно (хотя работает, но странно выглядит)
if (isActive == true) {
    System.out.println("Активно");
}

// Правильно
if (isActive) {
    System.out.println("Активно");
}

// Для false тоже просто
if (!isActive) {
    System.out.println("Неактивно");
}

5. Пытался использовать число как boolean

В некоторых языках можно писать if (1), и это означает true. В Java так нельзя.

int value = 1;

// Ошибка компиляции! Число ≠ boolean
if (value) { 
    System.out.println("Что-то");
}

// Правильно: явно сравниваем
if (value != 0) {
    System.out.println("Число не ноль");
}
Вот такие основные косяки. Если споткнулся на чем-то из этого, не переживай, через это проходят все.

Частые вопросы

В чем разница между & и &&?

& и | для чисел работают как побитовые операторы, а для boolean как логические, но без короткого замыкания: оба операнда вычисляются всегда, даже если результат уже понятен. && и || вычисляют правую часть только при необходимости. В реальной жизни почти всегда нужны && и ||: они и быстрее, и позволяют писать проверки вроде obj != null && obj.isReady().

Можно объединять условия в одном if?

Конечно! Через && и ||:

if (age >= 18 && hasPassport && !isBanned) {
    System.out.println("Заходи");
}

Когда использовать if, а когда switch?

if универсальный, подходит для любых проверок. switch удобнее, когда сравниваешь одну переменную с несколькими конкретными значениями. С Java 14 у него есть стрелочная форма case 1 -> ..., где не нужен break, и switch-выражение, которое сразу возвращает значение, а с Java 21 в case можно писать образцы (в том числе типы). Про него есть отдельная статья.

Что делать, если if-ов слишком много?

Подумай о рефакторинге. Можно вынести часть логики в отдельный метод, использовать switch, карты (Map), или паттерны проектирования. Длинная цепочка из 10+ else if это признак, что код пора улучшить.

Можно в условии вызывать методы?

Да, любое выражение, которое возвращает boolean:

if (text.isEmpty()) {
    System.out.println("Введите текст");
}

if (Math.random() > 0.5) {
    System.out.println("Повезло!");
}

В каком порядке проверяются условия в else if?

Строго сверху вниз. Как только Java находит первое истинное условие, она останавливается и выполняет соответствующий блок. Все остальные блоки (включая else) пропускаются. Поэтому в цепочке сначала пишут более узкие условия, а потом более широкие: если поставить score >= 60 первым, ветки для 90 и 80 никогда не сработают. Читайте также: