Menu

Операторы в Java: арифметические, сравнения, логические и присваивания

Как работают операторы Java - арифметические, сравнения, логические, присваивания, инкремента и тернарный оператор - а также целочисленное деление, приоритет и подводные камни, на которых спотыкаются новички.

На этой странице есть исполняемые редакторы: меняйте, запускайте и сразу видите результат.

Что делают операторы

Операторы - это символы, которые объединяют значения, чтобы вычислять новые. Вы уже используете их неформально - + складывает, > сравнивает - и Java группирует их в несколько семейств: арифметические, сравнения, логические, присваивания и пару особых, таких как инкремент и тернарный оператор.

Большинство операторов берут два значения (одно до символа, одно после) и выдают результат. Хитрость в том, чтобы знать, какого типа этот результат и в каком порядке они применяются - именно здесь спотыкаются новички.

Арифметические операторы

Пять арифметических операторов работают с числами: +, -, *, / и % (остаток).

Оператор % - это остаток от деления: 17 % 5 равно 2, потому что 5 укладывается в 17 три раза и остаётся 2. Это повседневный инструмент для проверки делимости - n % 2 == 0 это стандартная проверка «является ли n чётным?».

Обратите также внимание, что + выполняет двойную работу: с числами он складывает, но со String с любой стороны он соединяет текст.

Первая строка читается слева направо: "Total: " + 3 уже строка, поэтому 4 добавляется как текст. Заключите вычисление в скобки, когда хотите, чтобы оно выполнилось первым.

Подводный камень целочисленного деления

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

Чтобы получить дробный результат, сделайте хотя бы один операнд double - либо напишите его с .0, либо приведите одну сторону с помощью (double). Запись (double)(5 / 2) не помогает, потому что целочисленное деление 5 / 2 уже произошло до приведения; приводить нужно операнд, а не результат.

Операторы сравнения

Операторы сравнения задают вопрос «да/нет» и возвращают boolean. Их шесть: ==, !=, <, >, <=, >=.

Следите за разницей между = (присваивание - «положи это значение сюда») и == (сравнение - «равны ли они?»). Их путаница - классическая ошибка.

Важная оговорка: == сравнивает ссылки на объекты, а не их содержимое. Для строк используйте .equals().

Используйте == для примитивов вроде int и boolean, а .equals() - всякий раз, когда сравниваете содержимое объектов, таких как String.

Логические операторы

Логические операторы объединяют булевы значения: && (и), || (или) и ! (не). Именно так вы выражаете условия вроде «достаточно взрослый и есть билет».

&& и || работают с сокращённым вычислением: Java прекращает вычисление, как только ответ становится очевидным. С &&, если левая часть false, правая никогда не проверяется; с ||, если левая часть true, правая пропускается. Это не просто оптимизация - на это можно полагаться ради безопасности:

if (text != null && text.length() > 0) { ... }

Если text равно null, левая часть false и text.length() никогда не вызывается, что предотвращает NullPointerException. Поменяйте порядок - и программа упадёт.

Присваивание и инкремент

= присваивает, но в Java есть и составные присваивания, которые объединяют операцию с присваиванием: +=, -=, *=, /=, %=. А ++ / -- прибавляют или вычитают единицу.

++ бывает в двух видах: постфиксный (count++) возвращает старое значение, а затем увеличивает; префиксный (++count) сначала увеличивает, а затем возвращает новое значение. Разница важна только тогда, когда вы используете результат в том же выражении:

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

Тернарный оператор

Тернарный оператор condition ? a : b - это компактный if/else, который выдаёт значение: если условие true, он вычисляется в a, иначе в b.

Он хорош для коротких присваиваний «одно-или-другое». Не поддавайтесь искушению вкладывать тернарные операторы в тернарные - это быстро становится нечитаемым, и обычный if/else понятнее.

Приоритет и скобки

Операторы применяются в фиксированном порядке, во многом как в математике: *, /, % связываются крепче, чем + и -, которые связываются крепче, чем сравнения, которые связываются крепче, чем &&, а затем ||.

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

Далее: приведение типов

Несколько подводных камней отсюда - целочисленное деление, смешивание int и double - сводятся к типам. Намеренное преобразование между числовыми типами называется приведением (casting), и это тема следующей страницы.

Часто задаваемые вопросы

Что делает оператор % в Java?

% - это оператор остатка (modulo): он возвращает то, что остаётся после целочисленного деления. 7 % 3 равно 1, а 10 % 2 равно 0. Это стандартный способ проверить делимость (n % 2 == 0 означает, что n чётное) и уложить значение в заданный диапазон.

Почему 5 / 2 даёт в Java 2, а не 2.5?

Когда оба операнда - целые числа, / выполняет целочисленное деление и отбрасывает дробную часть, поэтому 5 / 2 равно 2, а не 2.5. Чтобы получить 2.5, хотя бы один операнд должен быть double: напишите 5.0 / 2, 5 / 2.0 или приведите одну сторону с помощью (double) 5 / 2.

В чём разница между == и equals() в Java?

== сравнивает примитивы по значению, но для объектов (включая String) сравнивает ссылки - один ли это и тот же объект в памяти. Чтобы сравнить содержимое объектов, используйте .equals(). Сравнение двух строк через == может вернуть false, даже если текст совпадает, поэтому для строк всегда используйте "a".equals(b).

Coddy programming languages illustration

Учитесь программировать с Coddy

НАЧАТЬ