Что делают операторы
Операторы - это символы, которые объединяют значения, чтобы вычислять новые. Вы уже используете их неформально - + складывает, > сравнивает - и 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).