HTML Diff
0 added 0 removed
Original 2026-01-01
Modified 2026-02-21
1 <p><a>#статьи</a></p>
1 <p><a>#статьи</a></p>
2 <ul><li>17 фев 2023</li>
2 <ul><li>17 фев 2023</li>
3 <li>0</li>
3 <li>0</li>
4 </ul><p>Знакомимся с основными инструментами языка и учимся работать с ними на практике.</p>
4 </ul><p>Знакомимся с основными инструментами языка и учимся работать с ними на практике.</p>
5 <p>Иллюстрация: Оля Ежак для Skillbox Media</p>
5 <p>Иллюстрация: Оля Ежак для Skillbox Media</p>
6 <p>Программист, музыкант. Знает Java, C# и Unity3D, но не собирается останавливаться на достигнутом.</p>
6 <p>Программист, музыкант. Знает Java, C# и Unity3D, но не собирается останавливаться на достигнутом.</p>
7 <p>Все мы со школы знакомы с математическими знаками<strong>+</strong> (<em>плюс</em>),<strong>-</strong> (<em>минус</em>),<strong>=</strong> (<em>равно</em>) и так далее. В Java и других языках программирования эти символы называются операторами<em>.</em>Они нужны для того, чтобы сообщить компилятору, какое действие совершать с <em>операндами</em> - числами, строками, объектами и другими значениями по обе стороны оператора.</p>
7 <p>Все мы со школы знакомы с математическими знаками<strong>+</strong> (<em>плюс</em>),<strong>-</strong> (<em>минус</em>),<strong>=</strong> (<em>равно</em>) и так далее. В Java и других языках программирования эти символы называются операторами<em>.</em>Они нужны для того, чтобы сообщить компилятору, какое действие совершать с <em>операндами</em> - числами, строками, объектами и другими значениями по обе стороны оператора.</p>
8 <em>Скриншот: Лев Сергеев для Skillbox Media</em><p>Например, на картинке выше<em>оператор</em>+ говорит компилятору: "Сложи два числа". Но на практике чисел в выражении может быть разное количество - и одно, и два, и три. В этих случаях и операторы будут называться по-разному:<strong>унарные</strong> - что-то делают с одним операндом,<strong>бинарные</strong> - с двумя, и тернарные - с тремя.</p>
8 <em>Скриншот: Лев Сергеев для Skillbox Media</em><p>Например, на картинке выше<em>оператор</em>+ говорит компилятору: "Сложи два числа". Но на практике чисел в выражении может быть разное количество - и одно, и два, и три. В этих случаях и операторы будут называться по-разному:<strong>унарные</strong> - что-то делают с одним операндом,<strong>бинарные</strong> - с двумя, и тернарные - с тремя.</p>
9 <p>В этой статье рассмотрим не только эти, но все основные виды операторов в Java:</p>
9 <p>В этой статье рассмотрим не только эти, но все основные виды операторов в Java:</p>
10 <ul><li><a>Присваивания</a></li>
10 <ul><li><a>Присваивания</a></li>
11 <li><a>Арифметические</a></li>
11 <li><a>Арифметические</a></li>
12 <li><a>Унарные</a></li>
12 <li><a>Унарные</a></li>
13 <li><a>Сравнения</a></li>
13 <li><a>Сравнения</a></li>
14 <li><a>Логические</a></li>
14 <li><a>Логические</a></li>
15 <li><a>Тернарный</a></li>
15 <li><a>Тернарный</a></li>
16 <li><a>Оператор instanceof</a></li>
16 <li><a>Оператор instanceof</a></li>
17 <li><a>Побитовые</a></li>
17 <li><a>Побитовые</a></li>
18 <li><a>Составные операторы присваивания</a></li>
18 <li><a>Составные операторы присваивания</a></li>
19 </ul><p>Ещё поговорим о <a>приоритетах операторов</a> - разберёмся, в каком порядке они выполняются. Если вы хотите просто освежить в памяти суть работы разных операторов, можете сразу перейти к <a>шпаргалке в конце статьи</a>.</p>
19 </ul><p>Ещё поговорим о <a>приоритетах операторов</a> - разберёмся, в каком порядке они выполняются. Если вы хотите просто освежить в памяти суть работы разных операторов, можете сразу перейти к <a>шпаргалке в конце статьи</a>.</p>
20 <p>Оператор присваивания в Java - это знак<strong>=</strong>(равно). Его задача - переложить значение переменной справа в переменную слева:</p>
20 <p>Оператор присваивания в Java - это знак<strong>=</strong>(равно). Его задача - переложить значение переменной справа в переменную слева:</p>
21 <em>Скриншот:<em>Лев Сергеев для Skillbox Media</em></em><p>Вот как это выглядит в коде (в комментариях - разбор синтаксиса):</p>
21 <em>Скриншот:<em>Лев Сергеев для Skillbox Media</em></em><p>Вот как это выглядит в коде (в комментариях - разбор синтаксиса):</p>
22 int x = 1; // Объявляем числовую переменную 'x' со значением 1 boolean a, b; // Объявляем логические переменные 'a' и 'b' a = b = true;<p><strong>Что происходит:</strong>значение true присваивается переменной b. В свою очередь, значение переменной b присваивается переменной a.</p>
22 int x = 1; // Объявляем числовую переменную 'x' со значением 1 boolean a, b; // Объявляем логические переменные 'a' и 'b' a = b = true;<p><strong>Что происходит:</strong>значение true присваивается переменной b. В свою очередь, значение переменной b присваивается переменной a.</p>
23 <p>Эти операторы выполняют простые арифметические действия: сложение, вычитание, умножение, деление и деление с остатком. Все арифметические операторы являются<em>бинарными</em> - то есть работают только с двумя значениями.</p>
23 <p>Эти операторы выполняют простые арифметические действия: сложение, вычитание, умножение, деление и деление с остатком. Все арифметические операторы являются<em>бинарными</em> - то есть работают только с двумя значениями.</p>
24 <p><strong>Что делает:</strong>складывает два операнда.</p>
24 <p><strong>Что делает:</strong>складывает два операнда.</p>
25 <p>Ещё этот оператор применяется при соединении двух строк в одну. Например, в Java можно выполнить выражение "Я люблю" + "Москву" и получить "Я люблю Москву". Такая операция в программировании называется конкатенацией.</p>
25 <p>Ещё этот оператор применяется при соединении двух строк в одну. Например, в Java можно выполнить выражение "Я люблю" + "Москву" и получить "Я люблю Москву". Такая операция в программировании называется конкатенацией.</p>
26 // Сложение чисел System.out.println(10 + 2); // Вывод: 12 // Конкатенация строк System.out.println("A" + "B"); // Вывод: AB // Сложение двух переменных типа 'char' System.out.println('a' + 'b'); // Вывод: 195<p>В Java типы данных<strong>char</strong>,<strong>byte</strong>и <strong>short</strong>при вычислениях неявно приводятся к типу<strong>int</strong>(целое число), поэтому с ними можно работать как с обычными числами. При этом тип данных<strong>char</strong>в Java отвечает за символы Unicode - каждый символ обозначает какое-то число. Например, символ<strong>a</strong>равен числу 97, а <strong>b</strong> - 98, поэтому в нашем примере и получилось значение 195.</p>
26 // Сложение чисел System.out.println(10 + 2); // Вывод: 12 // Конкатенация строк System.out.println("A" + "B"); // Вывод: AB // Сложение двух переменных типа 'char' System.out.println('a' + 'b'); // Вывод: 195<p>В Java типы данных<strong>char</strong>,<strong>byte</strong>и <strong>short</strong>при вычислениях неявно приводятся к типу<strong>int</strong>(целое число), поэтому с ними можно работать как с обычными числами. При этом тип данных<strong>char</strong>в Java отвечает за символы Unicode - каждый символ обозначает какое-то число. Например, символ<strong>a</strong>равен числу 97, а <strong>b</strong> - 98, поэтому в нашем примере и получилось значение 195.</p>
27 <p><strong>Что делает:</strong>вычитает из левого операнда правый.</p>
27 <p><strong>Что делает:</strong>вычитает из левого операнда правый.</p>
28 // Вычитание чисел System.out.println(10 - 2); // Вывод: 8<p><strong>Что делает:</strong>возвращает произведение операндов.</p>
28 // Вычитание чисел System.out.println(10 - 2); // Вывод: 8<p><strong>Что делает:</strong>возвращает произведение операндов.</p>
29 // Умножение чисел System.out.println(10 * 2); // Вывод: 20<p><strong>Что делает:</strong>делит левый операнд на правый.</p>
29 // Умножение чисел System.out.println(10 * 2); // Вывод: 20<p><strong>Что делает:</strong>делит левый операнд на правый.</p>
30 // Деление без остатка System.out.println(10 / 2); // Вывод: 5 System.out.println(11 / 2); // Вывод: 5 // Деление на 'double' System.out.println(11 / 2d); // Вывод: 5.5<p>А вот что будет, если попробовать поделить на ноль в Java:</p>
30 // Деление без остатка System.out.println(10 / 2); // Вывод: 5 System.out.println(11 / 2); // Вывод: 5 // Деление на 'double' System.out.println(11 / 2d); // Вывод: 5.5<p>А вот что будет, если попробовать поделить на ноль в Java:</p>
31 System.out.println(10 / 0); // Ошибка Вывод: Exception in thread "main" java.lang.ArithmeticException: / by zero<p>Делить число на ноль нельзя! Программа завершится, выбросив исключение. Но если привести выражение к типу 'double' (число с плавающей запятой), то вы получите "бесконечность":</p>
31 System.out.println(10 / 0); // Ошибка Вывод: Exception in thread "main" java.lang.ArithmeticException: / by zero<p>Делить число на ноль нельзя! Программа завершится, выбросив исключение. Но если привести выражение к типу 'double' (число с плавающей запятой), то вы получите "бесконечность":</p>
32 System.out.println(10 / 0d); // Вывод: Infinity<p><strong>Что делает:</strong>возвращает остаток от деления.</p>
32 System.out.println(10 / 0d); // Вывод: Infinity<p><strong>Что делает:</strong>возвращает остаток от деления.</p>
33 // Деление чисел по модулю (получение остатка от деления) System.out.println(10 % 2); // Вывод: 0 System.out.println(11 % 2); // Вывод: 1<p>Эти операторы в Java тоже можно отнести к арифметическим, но есть нюанс - они работают только с одним<em></em>операндом. Поэтому их и называют унарными.</p>
33 // Деление чисел по модулю (получение остатка от деления) System.out.println(10 % 2); // Вывод: 0 System.out.println(11 % 2); // Вывод: 1<p>Эти операторы в Java тоже можно отнести к арифметическим, но есть нюанс - они работают только с одним<em></em>операндом. Поэтому их и называют унарными.</p>
34 <p><strong>Что делают:</strong>меняют значение числа на положительное или отрицательное.</p>
34 <p><strong>Что делают:</strong>меняют значение числа на положительное или отрицательное.</p>
35 int positive = 1; int negative = -2; // Унарный минус System.out.println(-positive); // Вывод: -1 // Унарный плюс System.out.println(+negative); // Вывод: 2<p><strong>Что делают:</strong>инкремент - увеличивает значение переменной на единицу, а декремент - уменьшает.</p>
35 int positive = 1; int negative = -2; // Унарный минус System.out.println(-positive); // Вывод: -1 // Унарный плюс System.out.println(+negative); // Вывод: 2<p><strong>Что делают:</strong>инкремент - увеличивает значение переменной на единицу, а декремент - уменьшает.</p>
36 <p>В свою очередь, у декремента и инкремента есть две формы: префиксная и постфиксная. Звучит сложно, но на деле всё просто:</p>
36 <p>В свою очередь, у декремента и инкремента есть две формы: префиксная и постфиксная. Звучит сложно, но на деле всё просто:</p>
37 <ul><li><strong>Префиксные</strong>операторы (++x) сразу меняют значение переменной и подставляют его в выражение.</li>
37 <ul><li><strong>Префиксные</strong>операторы (++x) сразу меняют значение переменной и подставляют его в выражение.</li>
38 <li><strong>Постфиксные</strong>операторы (x++) делают наоборот - сначала используют старое значение переменной и только потом подставляют новое.</li>
38 <li><strong>Постфиксные</strong>операторы (x++) делают наоборот - сначала используют старое значение переменной и только потом подставляют новое.</li>
39 </ul>int a = 0, b = 0, c = 0, d = 0; // Префиксный инкремент/декремент System.out.println(++a); // Вывод: 1 System.out.println(--b); // Вывод: -1 // Постфиксный (значение переменных изменится после вывода в консоль) System.out.println(c++); // Вывод: 0 System.out.println(d--); // Вывод: 0<p>Инкременты и декременты часто используют в циклах в качестве счётчика, когда нужно по очереди вывести все числа в каком-то диапазоне:</p>
39 </ul>int a = 0, b = 0, c = 0, d = 0; // Префиксный инкремент/декремент System.out.println(++a); // Вывод: 1 System.out.println(--b); // Вывод: -1 // Постфиксный (значение переменных изменится после вывода в консоль) System.out.println(c++); // Вывод: 0 System.out.println(d--); // Вывод: 0<p>Инкременты и декременты часто используют в циклах в качестве счётчика, когда нужно по очереди вывести все числа в каком-то диапазоне:</p>
40 /* Префиксный инкремент в цикле. Сначала переменная i увеличивается на 1, а потом подставляется в цикл */ int i = 0; while (++i &lt; 3){ System.out.print(i); } Вывод: 12/* Постфиксный инкремент в цикле. Сперва выполняется цикл c начальным значением i, и только потом i увеличивается на 1:*/ int i = 0; while (i++ &lt; 3){ System.out.print(i); } Вывод: 123<p>Подробнее о декрементах и инкрементах можно почитать<a>в нашей статье</a> - рассказываем, как решать сложные выражения с этими операторами.</p>
40 /* Префиксный инкремент в цикле. Сначала переменная i увеличивается на 1, а потом подставляется в цикл */ int i = 0; while (++i &lt; 3){ System.out.print(i); } Вывод: 12/* Постфиксный инкремент в цикле. Сперва выполняется цикл c начальным значением i, и только потом i увеличивается на 1:*/ int i = 0; while (i++ &lt; 3){ System.out.print(i); } Вывод: 123<p>Подробнее о декрементах и инкрементах можно почитать<a>в нашей статье</a> - рассказываем, как решать сложные выражения с этими операторами.</p>
41 <p>В Java есть ещё два унарных оператора: ! - логическое отрицание, и ~ - побитовое отрицание, но их мы рассмотрим чуть позже, когда будем разбираться с логическими и побитовыми операторами.</p>
41 <p>В Java есть ещё два унарных оператора: ! - логическое отрицание, и ~ - побитовое отрицание, но их мы рассмотрим чуть позже, когда будем разбираться с логическими и побитовыми операторами.</p>
42 <p><strong>Что делают:</strong>сравнивают два операнда и выясняют отношения между ними - что больше, что меньше, что чему равняется. При вычислении такие операторы возвращают значение типа<strong>boolean</strong>:</p>
42 <p><strong>Что делают:</strong>сравнивают два операнда и выясняют отношения между ними - что больше, что меньше, что чему равняется. При вычислении такие операторы возвращают значение типа<strong>boolean</strong>:</p>
43 <ul><li><strong>true</strong>(правда);</li>
43 <ul><li><strong>true</strong>(правда);</li>
44 <li><strong>false</strong>(ложь).</li>
44 <li><strong>false</strong>(ложь).</li>
45 </ul><p>Всего в Java шесть операторов сравнения:</p>
45 </ul><p>Всего в Java шесть операторов сравнения:</p>
46 ОператорЧто означает<strong>==</strong>Равно<strong>&gt;</strong>Больше, чем<strong>&lt;</strong>Меньше, чем<strong>&gt;=</strong>Больше или равно<strong>&lt;=</strong>Меньше или равно<strong>!=</strong>Не равно<p>Давайте посмотрим, как выглядят операторы сравнения в коде - попробуем сравнить два целых числа и вывести результаты на экран:</p>
46 ОператорЧто означает<strong>==</strong>Равно<strong>&gt;</strong>Больше, чем<strong>&lt;</strong>Меньше, чем<strong>&gt;=</strong>Больше или равно<strong>&lt;=</strong>Меньше или равно<strong>!=</strong>Не равно<p>Давайте посмотрим, как выглядят операторы сравнения в коде - попробуем сравнить два целых числа и вывести результаты на экран:</p>
47 // В этом примере мы спрашиваем, равен ли ноль единице: System.out.println(1 == 0); // Вывод: false (ложь) // А здесь - больше ли единица, чем ноль: System.out.println(1 &gt; 0); // Вывод: true (правда) // Единица меньше или равна нулю? System.out.println(1 &lt;= 0); // Вывод: false (ложь)<p>Ещё операторы сравнения часто используют в условных конструкциях. Это когда, в зависимости от условий, выполняется какой-то один блок кода. В этом случае, помимо операторов сравнения, нам понадобятся операторы ветвления: if-else, switch и так далее. Например, здесь мы просим Java напечатать слово true, если 1 не равно 0:</p>
47 // В этом примере мы спрашиваем, равен ли ноль единице: System.out.println(1 == 0); // Вывод: false (ложь) // А здесь - больше ли единица, чем ноль: System.out.println(1 &gt; 0); // Вывод: true (правда) // Единица меньше или равна нулю? System.out.println(1 &lt;= 0); // Вывод: false (ложь)<p>Ещё операторы сравнения часто используют в условных конструкциях. Это когда, в зависимости от условий, выполняется какой-то один блок кода. В этом случае, помимо операторов сравнения, нам понадобятся операторы ветвления: if-else, switch и так далее. Например, здесь мы просим Java напечатать слово true, если 1 не равно 0:</p>
48 // Если '1' не равно '0', то напечатать "true" if(1 != 0) System.out.println("true"); // Вывод: true<p>Подробнее об операторах сравнения и условных конструкциях можно почитать<a>в этой статье</a>.</p>
48 // Если '1' не равно '0', то напечатать "true" if(1 != 0) System.out.println("true"); // Вывод: true<p>Подробнее об операторах сравнения и условных конструкциях можно почитать<a>в этой статье</a>.</p>
49 <p><strong>Что делают:</strong>комбинируют логические значения типа true и false.</p>
49 <p><strong>Что делают:</strong>комбинируют логические значения типа true и false.</p>
50 <p>В отличие от операторов сравнения, логические операторы работают не с отдельными числами, а с результатами выражений. Их часто используют в условных конструкциях - например, можно поставить рядом два выражения и выполнить какой-то блок кода, если одно из них возвращает true.</p>
50 <p>В отличие от операторов сравнения, логические операторы работают не с отдельными числами, а с результатами выражений. Их часто используют в условных конструкциях - например, можно поставить рядом два выражения и выполнить какой-то блок кода, если одно из них возвращает true.</p>
51 <p>Всего в Java шесть логических операторов, но чаще всего используют эти четыре:</p>
51 <p>Всего в Java шесть логических операторов, но чаще всего используют эти четыре:</p>
52 СимволЛогический операторЧто означает<strong>&amp;&amp;</strong>И (AND)Возвращает<em>true</em>, когда оба операнда<em>true</em>.<strong>||</strong>ИЛИ (OR)Возвращает<em>true</em>, когда хотя бы один операнд -<em>true</em>.<strong>^</strong>ИСКЛЮЧАЮЩЕЕ ИЛИ (XOR)Возвращает<em>true</em>, когда один операнд<em>true</em>, а второй -<em>false</em>.<strong>!</strong>НЕ (NOT)Инвертирует<em>true</em>в<em>false</em>и наоборот. Это унарный оператор - он работает только с каким-то одним выражением.<p>В качестве примера сравним несколько выражений:</p>
52 СимволЛогический операторЧто означает<strong>&amp;&amp;</strong>И (AND)Возвращает<em>true</em>, когда оба операнда<em>true</em>.<strong>||</strong>ИЛИ (OR)Возвращает<em>true</em>, когда хотя бы один операнд -<em>true</em>.<strong>^</strong>ИСКЛЮЧАЮЩЕЕ ИЛИ (XOR)Возвращает<em>true</em>, когда один операнд<em>true</em>, а второй -<em>false</em>.<strong>!</strong>НЕ (NOT)Инвертирует<em>true</em>в<em>false</em>и наоборот. Это унарный оператор - он работает только с каким-то одним выражением.<p>В качестве примера сравним несколько выражений:</p>
53 // AND - логическое умножение boolean a = (6 &gt; 5) &amp;&amp; (7 &gt; 4); System.out.println(a); // Результат: true, так как оба выражения true // OR - логическое сложение boolean b = (6 &gt; 5) || (7 &gt; 4); System.out.println(b); // Результат: true, так как одно из выражений true // XOR - логическое вычитание boolean c = (6 &gt; 8) ^ (6 &gt; 7); System.out.println(c); // Результат: false, так как оба выражения - false // NOT - логическое отрицание boolean d = (6 &gt; 5); System.out.println(!d); // Результат: false, так как изначальное выражение - true<p><strong>Как это работает.</strong>Допустим, у нас есть конструкция (6 &gt; 5) &amp;&amp; (7 &gt; 4). Когда мы начнём её выполнять, компилятор сначала проверит условия первого выражения, затем - второго. При этом оператор &amp;&amp; устроен так, что если оба выражения истинны, то он и сам вернёт true. А это как раз наш случай, потому что и 6 больше 5, и 7 больше 4.</p>
53 // AND - логическое умножение boolean a = (6 &gt; 5) &amp;&amp; (7 &gt; 4); System.out.println(a); // Результат: true, так как оба выражения true // OR - логическое сложение boolean b = (6 &gt; 5) || (7 &gt; 4); System.out.println(b); // Результат: true, так как одно из выражений true // XOR - логическое вычитание boolean c = (6 &gt; 8) ^ (6 &gt; 7); System.out.println(c); // Результат: false, так как оба выражения - false // NOT - логическое отрицание boolean d = (6 &gt; 5); System.out.println(!d); // Результат: false, так как изначальное выражение - true<p><strong>Как это работает.</strong>Допустим, у нас есть конструкция (6 &gt; 5) &amp;&amp; (7 &gt; 4). Когда мы начнём её выполнять, компилятор сначала проверит условия первого выражения, затем - второго. При этом оператор &amp;&amp; устроен так, что если оба выражения истинны, то он и сам вернёт true. А это как раз наш случай, потому что и 6 больше 5, и 7 больше 4.</p>
54 <p><strong>Что делает:</strong>сокращает условную конструкцию if-else до одной строчки.</p>
54 <p><strong>Что делает:</strong>сокращает условную конструкцию if-else до одной строчки.</p>
55 <p>Тернарный оператор (от латинского слова<em>ternarius</em> - "<em>тройной</em>") - это языковая конструкция, которая состоит из <em>трёх</em>операндов: логического условия и двух выражений. Если результат логического условия будет<em>true</em>, выполнится первое выражение, если<em>false</em> - второе. Записываются тернарные операторы так:</p>
55 <p>Тернарный оператор (от латинского слова<em>ternarius</em> - "<em>тройной</em>") - это языковая конструкция, которая состоит из <em>трёх</em>операндов: логического условия и двух выражений. Если результат логического условия будет<em>true</em>, выполнится первое выражение, если<em>false</em> - второе. Записываются тернарные операторы так:</p>
56 <em>Скриншот:<em>Лев Сергеев для Skillbox Media</em></em><p>Фишка в том, что таким образом мы можем записать конструкцию if-else всего одной строчкой. Допустим, нам нужно проверить булеву переменную condition - если она возвращает true, то переменная a = 100, а если false, то a = 200. Посмотрите, как легко это можно сделать с помощью тернарного оператора:</p>
56 <em>Скриншот:<em>Лев Сергеев для Skillbox Media</em></em><p>Фишка в том, что таким образом мы можем записать конструкцию if-else всего одной строчкой. Допустим, нам нужно проверить булеву переменную condition - если она возвращает true, то переменная a = 100, а если false, то a = 200. Посмотрите, как легко это можно сделать с помощью тернарного оператора:</p>
57 Слева - классическая конструкция if-else, справа - запись с помощью тернарного оператора<em>Скриншот:<em>Лев Сергеев для Skillbox Media</em></em><p>Кажется, что эти if-else теперь вообще больше не нужны. Мол, ставь везде тернарные операторы, и дело с концом. Однако в больших программах со сложной логикой это может повредить читаемости кода. Это в нашем примере выражение простое - а представьте, если в каждое выражение положить ещё по одному оператору. Получится неопрятно. Другому разработчику, который будет читать наш код, разобраться будет сложно.</p>
57 Слева - классическая конструкция if-else, справа - запись с помощью тернарного оператора<em>Скриншот:<em>Лев Сергеев для Skillbox Media</em></em><p>Кажется, что эти if-else теперь вообще больше не нужны. Мол, ставь везде тернарные операторы, и дело с концом. Однако в больших программах со сложной логикой это может повредить читаемости кода. Это в нашем примере выражение простое - а представьте, если в каждое выражение положить ещё по одному оператору. Получится неопрятно. Другому разработчику, который будет читать наш код, разобраться будет сложно.</p>
58 <p>Поэтому тернарные операторы рекомендуют использовать в тех случаях, когда условие простое и легко проверяется. А во всех остальных случаях прибегать к привычным "ифам" и "элсам".</p>
58 <p>Поэтому тернарные операторы рекомендуют использовать в тех случаях, когда условие простое и легко проверяется. А во всех остальных случаях прибегать к привычным "ифам" и "элсам".</p>
59 <p><strong>Что делает:</strong>проверяет, принадлежит ли объект к какому-то классу или интерфейсу, и возвращает булево значение - то есть true или false.</p>
59 <p><strong>Что делает:</strong>проверяет, принадлежит ли объект к какому-то классу или интерфейсу, и возвращает булево значение - то есть true или false.</p>
60 <p>Использование instanceof актуально, когда нужно проверить родителя объекта прямо во время выполнения программы. Например, если объекты приходят в ваш код из базы данных или другого потока выполнения и вам нужно убедиться, что к ним можно применять методы какого-то класса. Записывается instanceof так:</p>
60 <p>Использование instanceof актуально, когда нужно проверить родителя объекта прямо во время выполнения программы. Например, если объекты приходят в ваш код из базы данных или другого потока выполнения и вам нужно убедиться, что к ним можно применять методы какого-то класса. Записывается instanceof так:</p>
61 <em>Скриншот:<em>Лев Сергеев для Skillbox Media</em></em>import java.io.Serializable; public class Main { public static void main(String[] args) { // Объявляем ссылку типа 'Object' и кладём объект типа 'String' Object object = new String(); // 'true', так как в 'object' лежит объект 'String' System.out.println(object instanceof String); // 'true', так как 'object' наследник 'Object' System.out.println(object instanceof Object); // 'false', так как 'object' не принадлежит классу 'Math' System.out.println(object instanceof Math); // 'true', так как в 'object' лежит объект 'String', // а 'String' реализует интерфейс 'Serializable' System.out.println(object instanceof Serializable); } }<p><strong>Зачем нужны:</strong>чтобы писать алгоритмы, работающие с битами, - например, это полезно в криптографии и шифровании данных.</p>
61 <em>Скриншот:<em>Лев Сергеев для Skillbox Media</em></em>import java.io.Serializable; public class Main { public static void main(String[] args) { // Объявляем ссылку типа 'Object' и кладём объект типа 'String' Object object = new String(); // 'true', так как в 'object' лежит объект 'String' System.out.println(object instanceof String); // 'true', так как 'object' наследник 'Object' System.out.println(object instanceof Object); // 'false', так как 'object' не принадлежит классу 'Math' System.out.println(object instanceof Math); // 'true', так как в 'object' лежит объект 'String', // а 'String' реализует интерфейс 'Serializable' System.out.println(object instanceof Serializable); } }<p><strong>Зачем нужны:</strong>чтобы писать алгоритмы, работающие с битами, - например, это полезно в криптографии и шифровании данных.</p>
62 <p>В Java существует семь<em>побитовых операторов</em>. Четыре из них отвечают за побитовые вычисления. Они похожи на <em>логические</em>операции, только вместо<em>true</em>и <em>false</em>вы имеете дело с <strong>нулями</strong><em>и</em><strong>единицами</strong>в двоичной системе счисления. Каждый разряд вычисляется поочерёдно - но в отличие от математики, когда складываются две единицы, результат не переносится на старший разряд и ответом будет 1. Это как если бы мы считали столбиком, а всё, что "в уме", - выкидывали.</p>
62 <p>В Java существует семь<em>побитовых операторов</em>. Четыре из них отвечают за побитовые вычисления. Они похожи на <em>логические</em>операции, только вместо<em>true</em>и <em>false</em>вы имеете дело с <strong>нулями</strong><em>и</em><strong>единицами</strong>в двоичной системе счисления. Каждый разряд вычисляется поочерёдно - но в отличие от математики, когда складываются две единицы, результат не переносится на старший разряд и ответом будет 1. Это как если бы мы считали столбиком, а всё, что "в уме", - выкидывали.</p>
63 <p>Выглядит так:</p>
63 <p>Выглядит так:</p>
64 <em>Скриншот:<em>Лев Сергеев для Skillbox Media</em></em><p>Побитовые операторы вычисления бывают следующими:</p>
64 <em>Скриншот:<em>Лев Сергеев для Skillbox Media</em></em><p>Побитовые операторы вычисления бывают следующими:</p>
65 СимволЧто означает<strong>&amp;</strong>Побитовое И (AND) - умножение<strong>|</strong>Побитовое ИЛИ (OR) - сложение<strong>^</strong>Побитовое ИСКЛЮЧАЮЩЕЕ ИЛИ (XOR) - вычитание<strong>~</strong>Побитовое НЕ (NOT) - отрицание<p>Чтобы посмотреть, как работают побитовые вычисления в Java, переведём несколько десятичных чисел в двоичную систему счисления:</p>
65 СимволЧто означает<strong>&amp;</strong>Побитовое И (AND) - умножение<strong>|</strong>Побитовое ИЛИ (OR) - сложение<strong>^</strong>Побитовое ИСКЛЮЧАЮЩЕЕ ИЛИ (XOR) - вычитание<strong>~</strong>Побитовое НЕ (NOT) - отрицание<p>Чтобы посмотреть, как работают побитовые вычисления в Java, переведём несколько десятичных чисел в двоичную систему счисления:</p>
66 // Переводим числа от 1 до 8 в двоичную систему // 1 = 001 5 = 101 // 2 = 010 6 = 110 // 3 = 011 7 = 111 // 4 = 100 8 = 1000<p>Теперь попробуем выполнить с ними логические операции:</p>
66 // Переводим числа от 1 до 8 в двоичную систему // 1 = 001 5 = 101 // 2 = 010 6 = 110 // 3 = 011 7 = 111 // 4 = 100 8 = 1000<p>Теперь попробуем выполнить с ними логические операции:</p>
67 // 100 побитово умножить на 011 = 000 System.out.println(4 &amp; 3); // Вывод: 0 // 010 побитово сложить с 011 = 011 System.out.println(2 | 3); // Вывод: 3 // из 010 побитово вычесть 001 = 011 System.out.println(2 ^ 1); // Вывод: 3 // 000 инвертировать в ... 111 ? System.out.println(~0); // Вывод: -1<p>В последнем примере мы видим, что при побитовом отрицании числа 0, почему-то получается -1. Тут есть два нюанса:</p>
67 // 100 побитово умножить на 011 = 000 System.out.println(4 &amp; 3); // Вывод: 0 // 010 побитово сложить с 011 = 011 System.out.println(2 | 3); // Вывод: 3 // из 010 побитово вычесть 001 = 011 System.out.println(2 ^ 1); // Вывод: 3 // 000 инвертировать в ... 111 ? System.out.println(~0); // Вывод: -1<p>В последнем примере мы видим, что при побитовом отрицании числа 0, почему-то получается -1. Тут есть два нюанса:</p>
68 <ul><li>0 в нашем примере имеет тип int и занимает в памяти<strong>4 байта</strong> - то есть<strong>32 бита</strong>.</li>
68 <ul><li>0 в нашем примере имеет тип int и занимает в памяти<strong>4 байта</strong> - то есть<strong>32 бита</strong>.</li>
69 <li>Самый<em>старший бит</em>переменной (первый слева) является<em>знаковым</em>. Если он равен 0, то число будет<em>положительным</em>, а если 1 -<em>отрицательным</em>.</li>
69 <li>Самый<em>старший бит</em>переменной (первый слева) является<em>знаковым</em>. Если он равен 0, то число будет<em>положительным</em>, а если 1 -<em>отрицательным</em>.</li>
70 </ul><em>Скриншот:<em>Лев Сергеев для Skillbox Media</em></em><p>Если разобраться в концепции старшего бита, можно без труда освоить три оставшихся побитовых оператора, которые называются операторами<em>смещения битов:</em></p>
70 </ul><em>Скриншот:<em>Лев Сергеев для Skillbox Media</em></em><p>Если разобраться в концепции старшего бита, можно без труда освоить три оставшихся побитовых оператора, которые называются операторами<em>смещения битов:</em></p>
71 СимволЧто означает<strong>&lt;&lt;</strong>Сдвиг битов влево<strong>&gt;&gt;</strong>Сдвиг битов вправо<strong>&gt;&gt;<strong>&gt;</strong></strong><em>Беззнаковый</em>сдвиг битов вправо<p><em>Операторы сдвига</em>смещают все биты в левую или правую сторону, но делают это по-разному:</p>
71 СимволЧто означает<strong>&lt;&lt;</strong>Сдвиг битов влево<strong>&gt;&gt;</strong>Сдвиг битов вправо<strong>&gt;&gt;<strong>&gt;</strong></strong><em>Беззнаковый</em>сдвиг битов вправо<p><em>Операторы сдвига</em>смещают все биты в левую или правую сторону, но делают это по-разному:</p>
72 <ul><li>&gt;&gt; не трогает старший бит, оставляя число с тем же знаком (отрицательным или положительным). Ячейки отрицательных чисел при &gt;&gt; заполняются единицами.</li>
72 <ul><li>&gt;&gt; не трогает старший бит, оставляя число с тем же знаком (отрицательным или положительным). Ячейки отрицательных чисел при &gt;&gt; заполняются единицами.</li>
73 <li>&gt;&gt;&gt; и &lt;&lt; - затрагивают все биты. Освободившиеся ячейки справа заполняются нулями. Наполнение ячеек слева зависит от знака и оператора.</li>
73 <li>&gt;&gt;&gt; и &lt;&lt; - затрагивают все биты. Освободившиеся ячейки справа заполняются нулями. Наполнение ячеек слева зависит от знака и оператора.</li>
74 </ul><p>Звучит сложно, на деле - тоже сложно. Но попробуем разобраться на примере - разложим какое-то десятичное число на биты и посмотрим, как работает смещение битов.</p>
74 </ul><p>Звучит сложно, на деле - тоже сложно. Но попробуем разобраться на примере - разложим какое-то десятичное число на биты и посмотрим, как работает смещение битов.</p>
75 <p>В Java есть метод toBinaryString(), который показывает, как выглядят десятичные числа в двоичной системе. Но двоичные числа - это ещё не биты. Например, число <strong>2</strong>занимает<strong>32</strong>бита, но если обработать его методом toBinaryString(), на экране появятся только два из них: 1 и 0. Оставшиеся 30 нулей просто "обрезаются". Это происходит по той же причине, по которой мы, например, не пишем десятичное число 9 как 009.</p>
75 <p>В Java есть метод toBinaryString(), который показывает, как выглядят десятичные числа в двоичной системе. Но двоичные числа - это ещё не биты. Например, число <strong>2</strong>занимает<strong>32</strong>бита, но если обработать его методом toBinaryString(), на экране появятся только два из них: 1 и 0. Оставшиеся 30 нулей просто "обрезаются". Это происходит по той же причине, по которой мы, например, не пишем десятичное число 9 как 009.</p>
76 System.out.print(Integer.toBinaryString(2)); Вывод: 10<p>Поэтому, чтобы лучше разобраться в работе побитовых операторов, лучше использовать модифицированный метод BinaryString, который раскладывает на биты уже так, как надо:</p>
76 System.out.print(Integer.toBinaryString(2)); Вывод: 10<p>Поэтому, чтобы лучше разобраться в работе побитовых операторов, лучше использовать модифицированный метод BinaryString, который раскладывает на биты уже так, как надо:</p>
77 // Метод добавляет к бинарному значению все недостающие биты и выводит их на экран public static void printBinaryString(int hexNumber){ String bits = Integer.toBinaryString(hexNumber); String allBits = "00000000000000000000000000000000" .substring(0, 32 - bits.length()) + bits; System.out.printf("%11d : %s\n", hexNumber, allBits); }<p>Сдвинув биты числа 1 два раза влево, мы получаем 4. А если потом сдвинуть их ещё 29 раз, получится минимальное значение типа int: -2 147 483 648.</p>
77 // Метод добавляет к бинарному значению все недостающие биты и выводит их на экран public static void printBinaryString(int hexNumber){ String bits = Integer.toBinaryString(hexNumber); String allBits = "00000000000000000000000000000000" .substring(0, 32 - bits.length()) + bits; System.out.printf("%11d : %s\n", hexNumber, allBits); }<p>Сдвинув биты числа 1 два раза влево, мы получаем 4. А если потом сдвинуть их ещё 29 раз, получится минимальное значение типа int: -2 147 483 648.</p>
78 printBinaryString(1); printBinaryString(1 &lt;&lt; 2); // Смещаем биты числа '1' влево на 2 позиции printBinaryString(4 &lt;&lt; 29); // Смещаем биты числа '4' влево на 29 позиций Вывод: 1 : 00000000000000000000000000000001 4 : 00000000000000000000000000000100 -2147483648 : 10000000000000000000000000000000<p>Теперь попробуем сдвинуть наши биты уже в обратную сторону. Обратите внимание, как различается работа &gt;&gt; и &gt;&gt;&gt;. В первом случае всё заполнится единицами и вы получите минусовое значение, а во втором на выходе будут просто нули.</p>
78 printBinaryString(1); printBinaryString(1 &lt;&lt; 2); // Смещаем биты числа '1' влево на 2 позиции printBinaryString(4 &lt;&lt; 29); // Смещаем биты числа '4' влево на 29 позиций Вывод: 1 : 00000000000000000000000000000001 4 : 00000000000000000000000000000100 -2147483648 : 10000000000000000000000000000000<p>Теперь попробуем сдвинуть наши биты уже в обратную сторону. Обратите внимание, как различается работа &gt;&gt; и &gt;&gt;&gt;. В первом случае всё заполнится единицами и вы получите минусовое значение, а во втором на выходе будут просто нули.</p>
79 printBinaryString(Integer.MIN_VALUE); // Смещаем биты числа '-2147483648' вправо на 16 printBinaryString(Integer.MIN_VALUE &gt;&gt; 16); // Беззнаковое смещение битов числа '-2147483648' вправо на 16 printBinaryString(Integer.MIN_VALUE &gt;&gt;&gt; 16); Вывод: -2147483648 : 10000000000000000000000000000000 -32768 : 11111111111111111000000000000000 32768 : 00000000000000001000000000000000<p><strong>Как это работает.</strong>С помощью операторов &gt;&gt; и &gt;&gt;&gt; мы сдвигаем все биты числа вправо. Но при обычном сдвиге (&gt;&gt;) отрицательное число остаётся отрицательным, потому что мы не трогаем старший бит. При беззнаковом сдвиге (&gt;&gt;&gt;) наоборот - отрицательное станет положительным, потому что мы затронем эту значимую единицу.</p>
79 printBinaryString(Integer.MIN_VALUE); // Смещаем биты числа '-2147483648' вправо на 16 printBinaryString(Integer.MIN_VALUE &gt;&gt; 16); // Беззнаковое смещение битов числа '-2147483648' вправо на 16 printBinaryString(Integer.MIN_VALUE &gt;&gt;&gt; 16); Вывод: -2147483648 : 10000000000000000000000000000000 -32768 : 11111111111111111000000000000000 32768 : 00000000000000001000000000000000<p><strong>Как это работает.</strong>С помощью операторов &gt;&gt; и &gt;&gt;&gt; мы сдвигаем все биты числа вправо. Но при обычном сдвиге (&gt;&gt;) отрицательное число остаётся отрицательным, потому что мы не трогаем старший бит. При беззнаковом сдвиге (&gt;&gt;&gt;) наоборот - отрицательное станет положительным, потому что мы затронем эту значимую единицу.</p>
80 <p><strong>Зачем нужны:</strong>чтобы записывать выражения короче и автоматически приводить операнды к единому типу.</p>
80 <p><strong>Зачем нужны:</strong>чтобы записывать выражения короче и автоматически приводить операнды к единому типу.</p>
81 <p>В Java есть сокращённые формы операторов присваивания - составные. Такие операторы выполняют действие между<strong>x</strong>и <strong>y</strong>, а получившееся значение помещают в <strong>x</strong>. Выглядят составные операторы так:</p>
81 <p>В Java есть сокращённые формы операторов присваивания - составные. Такие операторы выполняют действие между<strong>x</strong>и <strong>y</strong>, а получившееся значение помещают в <strong>x</strong>. Выглядят составные операторы так:</p>
82 <em>Скриншот:<em>Лев Сергеев для Skillbox Media</em></em><p>Плюс составных операторов в том, что они записываются короче и неявно приводят переменные к одному типу, если эти типы различаются. Например, в сокращённом варианте можно сложить дроби и числа без приведения, и нам за это ничего не будет. А в полной записи будет ошибка:</p>
82 <em>Скриншот:<em>Лев Сергеев для Skillbox Media</em></em><p>Плюс составных операторов в том, что они записываются короче и неявно приводят переменные к одному типу, если эти типы различаются. Например, в сокращённом варианте можно сложить дроби и числа без приведения, и нам за это ничего не будет. А в полной записи будет ошибка:</p>
83 int x = 1; double y = 3.1415d; x = x + y; // Эта строка не скомпилируется x += y; // А здесь всё хорошо // Оператор += в развёрнутом виде x = (int)(x + y);<p>У каждого оператора Java есть свой приоритет. Чем он выше, тем раньше оператор выполнится в выражении. Бинарные и тернарный операторы (кроме присваивания) выполняются слева направо, а остальные (унарные и присваивания) - справа налево.</p>
83 int x = 1; double y = 3.1415d; x = x + y; // Эта строка не скомпилируется x += y; // А здесь всё хорошо // Оператор += в развёрнутом виде x = (int)(x + y);<p>У каждого оператора Java есть свой приоритет. Чем он выше, тем раньше оператор выполнится в выражении. Бинарные и тернарный операторы (кроме присваивания) выполняются слева направо, а остальные (унарные и присваивания) - справа налево.</p>
84 <strong>Приоритет</strong><strong>(снизу вверх)</strong>ГруппаОператоры13Постфиксныеx++ x--12Унарные++x --x +x -x ~x !x11Мультипликативные* / %10Аддитивные+ -9Сдвига битов&lt;&lt; &gt;&gt; &gt;&gt;&gt;8Сравнения&lt; &gt; &lt;= &gt;= instanceof7Равенства== !=6Побитовое И&amp;5Побитовое исключающее ИЛИ^4Побитовое ИЛИ|3Логическое И&amp;&amp;2Логическое ИЛИ||1Тернарный? :0Присваивания= += -= *= /= %=&amp;= ^= |=&lt;&lt;= &gt;&gt;= &gt;&gt;&gt;=<p>Мы рассмотрели все основные операторы в Java и их работу на примерах. Попробуем кратко резюмировать, что нужно вынести из этой статьи:</p>
84 <strong>Приоритет</strong><strong>(снизу вверх)</strong>ГруппаОператоры13Постфиксныеx++ x--12Унарные++x --x +x -x ~x !x11Мультипликативные* / %10Аддитивные+ -9Сдвига битов&lt;&lt; &gt;&gt; &gt;&gt;&gt;8Сравнения&lt; &gt; &lt;= &gt;= instanceof7Равенства== !=6Побитовое И&amp;5Побитовое исключающее ИЛИ^4Побитовое ИЛИ|3Логическое И&amp;&amp;2Логическое ИЛИ||1Тернарный? :0Присваивания= += -= *= /= %=&amp;= ^= |=&lt;&lt;= &gt;&gt;= &gt;&gt;&gt;=<p>Мы рассмотрели все основные операторы в Java и их работу на примерах. Попробуем кратко резюмировать, что нужно вынести из этой статьи:</p>
85 <ul><li><strong>Оператор</strong><em></em>- это языковая конструкция, которая выполняет действие над операндом.</li>
85 <ul><li><strong>Оператор</strong><em></em>- это языковая конструкция, которая выполняет действие над операндом.</li>
86 <li><strong>Операнд</strong><em> - это</em>число, переменная, объект и так далее, с которыми оператор совершает какие-то действия (например, арифметическое и логическое).</li>
86 <li><strong>Операнд</strong><em> - это</em>число, переменная, объект и так далее, с которыми оператор совершает какие-то действия (например, арифметическое и логическое).</li>
87 <li><strong>Операторы</strong>бывают<strong>унарные</strong>,<strong>бинарные</strong>и <strong>тернарные</strong> - это зависит от того, сколько операндов они обрабатывают.</li>
87 <li><strong>Операторы</strong>бывают<strong>унарные</strong>,<strong>бинарные</strong>и <strong>тернарные</strong> - это зависит от того, сколько операндов они обрабатывают.</li>
88 <li><strong>Арифметические операторы</strong>нужны для простых математических действий: сложения, вычитания, умножения, деления и деления с остатком.</li>
88 <li><strong>Арифметические операторы</strong>нужны для простых математических действий: сложения, вычитания, умножения, деления и деления с остатком.</li>
89 <li><strong>Унарные операторы</strong>работают только с одним операндом. Это унарные минус и плюс, инкремент, декремент, логическое и побитовое отрицание.</li>
89 <li><strong>Унарные операторы</strong>работают только с одним операндом. Это унарные минус и плюс, инкремент, декремент, логическое и побитовое отрицание.</li>
90 <li><strong>Операторы сравнения</strong>сопоставляют значения двух операторов и возвращают ответ - true или false.</li>
90 <li><strong>Операторы сравнения</strong>сопоставляют значения двух операторов и возвращают ответ - true или false.</li>
91 <li><strong>Логические операторы</strong>заточены уже не на числа, а на целые выражения - и на их основе создают сложные условия, например, для работы в циклах.</li>
91 <li><strong>Логические операторы</strong>заточены уже не на числа, а на целые выражения - и на их основе создают сложные условия, например, для работы в циклах.</li>
92 <li><strong>Тернарный оператор</strong>умеет работать сразу с тремя операндами: условием и двумя выражениями. То есть им вполне можно заменить ветвления типа if-else.</li>
92 <li><strong>Тернарный оператор</strong>умеет работать сразу с тремя операндами: условием и двумя выражениями. То есть им вполне можно заменить ветвления типа if-else.</li>
93 <li><strong>Оператор</strong><strong>instanceof</strong>определяет принадлежность объекта к классу.</li>
93 <li><strong>Оператор</strong><strong>instanceof</strong>определяет принадлежность объекта к классу.</li>
94 <li><strong>Побитовые операторы</strong>нужны для проведения операций с битами - если упростить, то с нулями и единицами в двоичной системе счисления.</li>
94 <li><strong>Побитовые операторы</strong>нужны для проведения операций с битами - если упростить, то с нулями и единицами в двоичной системе счисления.</li>
95 <li><strong>Составные операторы</strong>неявно приводят типы данных, если они разные.</li>
95 <li><strong>Составные операторы</strong>неявно приводят типы данных, если они разные.</li>
96 <li>У каждого оператора есть свой<strong>приоритет</strong>.</li>
96 <li>У каждого оператора есть свой<strong>приоритет</strong>.</li>
97 </ul><p>Для более глубокого понимания темы можно почитать другие наши статьи: "<a><em>Тип Boolean и операторы сравнения в Java</em></a>" и "<a><em>Логические операторы в Java</em></a>". А если хотите совсем хорошо разобраться, почитайте<a>официальную документацию</a>Java - это вообще лучший способ освоить язык со всеми его тонкостями.</p>
97 </ul><p>Для более глубокого понимания темы можно почитать другие наши статьи: "<a><em>Тип Boolean и операторы сравнения в Java</em></a>" и "<a><em>Логические операторы в Java</em></a>". А если хотите совсем хорошо разобраться, почитайте<a>официальную документацию</a>Java - это вообще лучший способ освоить язык со всеми его тонкостями.</p>
98 <a>Научитесь: Профессия Java-разработчик + ИИ Узнать больше</a>
98 <a>Научитесь: Профессия Java-разработчик + ИИ Узнать больше</a>