JavaRush /Курсы /Java Syntax Pro /Нюансы работы различных операторов

Нюансы работы различных операторов

Java Syntax Pro
8 уровень , 6 лекция
Открыта

1. Булевы операции

Операторы | и & можно применять не только к числам, но и к выражениям типа boolean.

Однако, как вы уже знаете, для логических выражений есть операторы && и ||. Что же нам даст использование | вместо || и использование & вместо &&? Есть ли вообще в этом смысл? Оказывается, есть. Иногда.

Логические операторы || и && выполняются слева направо по так называемому ленивому принципу.

(выражение1) || (выражение2) || (выражение3)

Если выражение1 равно true, нет смысла вычислять выражение2 и выражение3: результат все равно будет true.

Поэтому при вычислении выражений (а они вычисляются по порядку слева направо), как только мы получили true, вычисление остальных выражений пропускается. И если в выражениях выражение2 и выражение3 были вызовы каких-нибудь функций, то эти функции не вызываются!

То же самое и для логического оператора &&:

(выражение1) && (выражение2) && (выражение3)

Если выражение1 равно false, нет смысла вычислять выражение2 и выражение3: результат все равно будет false.

Это важный момент, который позволяет писать вещи вида:

String s = null;
if (s != null && s.length() > 0) {

В примере выше мы никогда не получим NullPointerException, т.к. выражение s.length() будет выполняться только если первая часть s != null равна true.

Если s окажется равно null, слева от оператора && будет значение false, и результат всего логического выражения будет false, поэтому вычисления второй части (s.length() > 0) не происходит.

Вот это все к чему:

Если в логическом выражении использовать оператор | или оператор &, то ленивого вычисления не происходит — в любом случае будут вычислены все выражения.



2. Приоритет операций в Java

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

Операторы в Java тоже имеют приоритет. Только: а) их несколько больше, б) у некоторых операторов действия выполняются слева направо, а у других — справа налево.

Вот как выглядит таблица со всеми операторами Java:

Категория Оператор Ассоциативность
Постфикс () [] . Слева направо
Унарный ++ -- ! ~ Справа налево
Мультипликативный * / % Слева направо
Аддитивный + - Слева направо
Сдвиг >> >>> << Слева направо
Реляционный > >= < <= Слева направо
Равенство == != Слева направо
Побитовое И (AND) & Слева направо
Исключающее ИЛИ (XOR) ^ Слева направо
Побитовое ИЛИ (OR) | Слева направо
Логическое И (AND) && Слева направо
Логическое ИЛИ (OR) || Слева направо
Условный ?: Справа налево
Присваивание = += -= *= /= %= >>= <<= &= ^= |= Справа налево
Запятая , Слева направо

В верхней строке идут самые приоритетные операторы. Круглые скобки () используются для явной установки приоритета. Квадратные скобки [] используются для индексирования переменной-массива. Оператор . используется для получения полей и методов у ссылки на объект или класс.

Чем ниже операторы расположены в таблице, тем ниже их приоритет.

Если вы используете несколько операторов в вашем выражении, не ленитесь: ставьте скобки.

Да, в Java можно написать что-то типа if (a & 1<<b > ~c), но так делать не стоит. Вы пишете код не только для компилятора, но и для других программистов. Чем код читабельнее, тем лучше.



3. Префиксный и постфиксный инкремент

Как вы уже знаете, в Java есть оператор инкремента (++) и оператор декремента (--), которые увеличивают (и уменьшают) значение переменной на 1.

Чего вы скорее всего не знаете, так это того, что есть два вида этих операций: префиксные – оператор ставится до переменной, и постфиксные — оператор ставится после переменной. И работают эти операторы немного по-разному.

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

int a = 5;
int b = a++;

Если оператор ++ стоит после переменной и переменная участвует в каком-то выражении (как в примере выше), то в выражении будет использовано текущее значение переменной, а только потом она будет увеличена на 1.

Другими словами, произойдет примерно это:

int a = 5;
int b = a;
a = a + 1;

Т.е. b будет иметь значение 5, а не 6, как это могло показаться вначале.

Если же оператор ++ стоит до переменной и переменная участвует в каком-то выражении, она сначала будет увеличена на 1, а только затем ее значение будет участвовать в выражении.

int a = 5;
int b = ++a;

Пример выше эквивалентен следующему примеру:

int a = 5;
a = a + 1;
int b = a;

Вот тут уже значение b будет равно 6.

Есть даже один пример, который используется Java-программистами, чтобы определить, что их собеседник тоже Java-программист:

int a = 5;
int b = ++a++a;

Да, так тоже можно писать.

Этот пример отлично скомпилируется и превратится примерно в это:

int a = 5;

a = a + 1;
int v1 = a;

a = a + 1;
int v2 = a;

int b = v1 + v2;

Для оператора -- все точно то же самое.



Комментарии (311)
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ
Grigoryvvv Уровень 14 Expert
21 октября 2025
21.10.2025 / 9 уровень Для понимания решения сложных выражений с префиксными и постфиксными инкрементами и декрементами, рекомендую к прочтению: https://edu.sravni.ru/kursy/info/inkrement-i-dekrement/ лишний раз убеждаемся что программирование и математика это не одно и то же 😬
Eugene Volkov Уровень 35
17 сентября 2025
как?! кааааак?! как вообще оператор > или < т.е. реляционный в итоге присваивает значение целочисленному типу? я ни хрена не понимаю. где это бвло объяснено? кпк этим пользоваться? что жто за х?рня? обновлено. первую задачу вроде понял. но собираюсь у??нуться на второй обновлено: как то а течение минуты 2ю решил. но чувмтвую третья бкдет жесть обновлено: я хренею. 3ю зпдачу решил за минуту или две
DM Уровень 10
19 августа 2025
++a + (a++ * --a) // 20 - это не верно ++a + (a-- * ++a); // 20 a это верно 🤡
Anonymous #3541949 Уровень 14
8 июля 2025
пожалуйста, скажите, что не я один сделал все побитовые задания наугад😢
makise Уровень 3
5 июля 2025
Полезная лекция
Anonymous #3585174 Уровень 33
12 июня 2025
like
Nadezhda Уровень 28
28 мая 2025
Выражение вычисляется справа налево по приоритету операторов, но переменные читаются слева направо. То есть, сначала в выражение подставляются все переменные, и всякие а++ изменяют исходное значение переменной "а", которое потом может быть подставлено дальше по выражению в уже измененном виде; затем начинаются арифметические действия согласно приоритету операндов.
Елена Пашина Уровень 10 Expert
14 мая 2025
Про последнюю задачу - спустя часы поняла, кажется) Сначала мы проставляем значения инкрементов, затем выполняем мат.операцию с получившимися числами, учитывая приоритетность скобок. Мы просто идём последовательно по этим инкрементам слева направо, и каждый раз подставляем новое значение в выражение для переменной b, но при этом каждый раз меняем и переменную а (и где-то себе в уме её промежуточное значение записываем). То есть если попробовать объяснить само условие задачи,

int a = 3;
int b = a++ + (--a * a++);
System.out.println(b);
будет так:

Движемся слева направо: а++ //вписываем 3, получаем b = 3 + (…), но после этого действия a стало = 4).
Далее встречаем --а //тут ставим сразу 3, тк a на предыдущем шаге было 4, и а становится = 3.
Получаем пока b = 3 + (3 * …).
Далее встречаем а++ //и это сначала 3. Но после этого в переменную а записываем 4.
И по итогу b = 3 + (3 * 3) = 12, что и выведется в консоль. А а = 4.
Действие в скобках при вычислении инкрементов не приоритет! Только после того, как мы их вычислим и будем считать само выражение - тогда и начнём со скобок. Это всё хорошо объясняется в статье https://skillbox.ru/media/base/inkrement_i_dekrement_v_java/ .
Любовь Уровень 10
6 июня 2025
Огромное спасибо! статья действительно полезная и помогла разобраться в теме
Михаил Уровень 2
22 июля 2025
Согласен с предыдущим комментарием! Спасибо, мне тоже помогла статья)
Михаил Уровень 2
22 июля 2025
Согласен с предыдущим комментарием! Спасибо, мне тоже помогла статья)
Vadim Уровень 17
26 августа 2025
да, статья нормас, объясняют прям пошагово.
Boris Уровень 19
13 сентября 2025
Спасибо.
Виктор Уровень 26
6 мая 2025
Можно добавить к примеру " ++а + ++а" числовые значения, мне было бы тогда легче понять тогда что к чему.
Алексей Уровень 1
30 апреля 2025
2 часа потратил что бы понять что в приоритете сначала (), потом инкременты. 1:59 понадобилось что бы понять что в этой таблице выше указаны приоритеты, а не только ассоциативность