Операторы Java: основные типы, примеры операций
Программирование • 14 марта 2023 • 5 мин чтения
Разбираем, что начинающим разработчикам нужно знать об операторах Java, чтобы написать свой первый код.
- Основные виды операторов Java и их предназначение
- Операторы присваивания
- Арифметические операторы
- Операторы сравнения
- Логические операторы
- Побитовые операторы
- Прочие операторы
Основные виды операторов Java и их предназначение
Чтобы понять, как работают операторы Java, нужно хорошо представлять, как устроен этот язык программирования. Любой код на Java состоит из инструкций и выражений. По сути, и то и другое — просто фрагменты кода. Разница между ними в том, за что они отвечают.
Инструкции ― каркас программы, к ним относят условные конструкции, циклы и классы. Например, if, if-else, while, for. Они задают маршрут, по которому компьютер будет обрабатывать код, но сами никаких действий не производят и не возвращают результат. За эту часть в Java отвечают выражения. С их помощью программисты работают с данными и проводят вычисления.
Выражения в Java состоят из операндов и операторов. Операторы — это команды, которые указывают компьютеру, какие действия нужно совершить над операндами. Например, в выражении 1 + 2 оба числа будут операндами, а знак сложения — оператором. Операторы языка Java позволяют выстраивать выражения любой сложности, на основе которых компьютер выполнит вычисления и вернёт значение.
В Java операторы делятся на пять основных групп:
● Операторы присваивания
● Арифметические операторы
● Операторы сравнения
● Логические операторы
● Побитовые операторы
Есть и другие операторы, которые решают свои специфические задачи. Например, с помощью укороченных операторов программисты комбинируют разные типы операторов Java, чтобы компьютер быстрее обрабатывал код и его было проще читать.
Чтобы написать код, который будет корректно работать, новичку нужно понимать, какие есть типы операторов Java и что они делают. На курсе «Java-разработчик» студенты изучают самые используемые группы операторов и практикуются работать с ними в тренажёре.
Получите востребованную профессию в IT
Научитесь создавать приложения с нуля за 10 месяцев, получите 5 проектов в портфолио и помощь с трудоустройством. Начните с бесплатной вводной части курса «Java-разработчик».
Операторы присваивания
Разработчики редко используют в выражениях числа ― чаще записывают значения в переменные и обращаются к ним по ходу программы. Чтобы задать переменной нужное значение, используют оператор присваивания. Это самый простой пример оператора в Java.
Выглядит он как знак равенства. Например, в выражении x = 1 переменной x присвоилось значение 1. И в любых выражениях, где присутствует x, компьютер будет подставлять на его место единицу, пока разработчик не перепишет значение этой переменной.
С помощью оператора присваивания можно записать в переменную результат вычисления. Например, x = 1 + 2. Теперь компьютер присвоит переменной x значение 3.
В переменную можно даже записать результат другого присваивания. Например, х = у = 1. В переменную x запишется результат выражения y = 1. Если y изменится, вслед за ним изменится и x. Здесь важно помнить, что в Java данные перетекают справа налево.
Арифметические операторы
Арифметические или математические операторы Java программисты используют, когда нужно произвести простые вычисления: сложить, разделить, умножить.
В языке Java эти операторы работают так же, как в математике, но в программировании у них есть свои особенности. Например, плюс позволяет сложить два числа, две строки или два значения разных типов
У оператора деления — своя специфика. Например, результатом выражения 10 / 3 будет тройка. Почему так? Когда оператор применяется к целым числам, остаток от деления отбрасывается, чтобы результатом тоже было целое число. Получить остаток от деления позволяет другой оператор — %. Например, остатком от деления 10 на 3 будет единица. Её и вернёт оператор %.
Минус в Java тоже имеет двойной смысл: когда этот оператор применяют к двум операндам, минус называют бинарным. В этом случае речь идёт о вычитании. Например, 10 — 3 = 7. Когда же минус относится только к одному операнду, его называют унарным — он указывает, что значение операнда будет отрицательным: x = -1.
Большую часть математических операций в Java разработчики выполняют с помощью библиотек. Они содержат готовые функции для вычисления синусов, косинусов, возведения в степень и более сложных арифметических действий.
Операторы сравнения
Операторы сравнения Java, иногда их ещё называют операторами отношения, имеют честный математический смысл — сопоставить две величины между собой.
Результатом вычисления всегда будет булевое значение — true или false, то есть истина или ложь
Операторы сравнения очень точные ― они сравнивают не только сами данные, но и их тип. Из очевидного: нельзя сравнить строку с числом. Программа выдаст ошибку, потому что это объекты разного типа.
Есть тонкости, которые новичкам нужно учитывать. Например, в Java есть тип данных int — целое число, а есть класс Integer, куда входит тип int. При попытке сравнить объект типа int с int результат будет верный, а вот при сравнении двух объектов типа Integer компьютер выдаст ошибку, поскольку для машины это разные объекты. Тот же результат получится, если сравнивать между собой строки. Для объектов типа String, Integer и аналогичных оператор сравнения не применяют.
Логические операторы
Программист может заранее не знать, каким будет результат вычислений. Обычно так и бывает, если данные для обработки компьютер получает извне уже в процессе выполнения кода. При этом программа должна быть корректной. В этом случае в ход идут логические операторы Java.
Логические операторы работают с булевыми значениями true или false и помогают запрограммировать дальнейшие действия компьютера в привязке к полученному результату: true — иди налево, false — иди направо. Сами по себе они не решают, а лишь обеспечивают проверку, результатом которой будет определяющее true или false
Логическое НЕ выполняет роль отрицания и придаёт операнду или выражению, перед которым стоит, обратное значение.
Чтобы представить, как работают два других оператора, можно провести параллель с математикой. Такая аналогия поможет быстрее запомнить, в чём разница.
Логическое ИЛИ ещё называют логическим сложением — этот оператор работает так же, как плюс в математике. Только в двоичной системе, где true — это 1, false — это 0, а 1 + 1 = 1, потому что двойки в этой системе попросту не существует.
1 + 0 = 1
0 + 1 = 1
1 + 1 = 1
0 + 0 = 0
Логическое И можно представить как умножение в двоичной системе.
1 * 0 = 0
0 * 1 = 0
0 * 0 = 0
1 * 1 = 1
Логические операторы Java позволяют компьютеру не проверять всё выражение, если результат очевиден по первому операнду. Так код выполняется быстрее.
Побитовые операторы
Любое число в Java можно представить в виде цепочки битов, состоящей из нулей и единиц. Старший бит в цепочке, который стоит первым слева, всегда указывает на знак числа: положительное — 0, отрицательное — 1. Нули в начале цепочки обычно опускают для простоты восприятия. Например, число 5 в двоичной системе счисления обычно записывают как 101, хотя на самом деле оно выглядит как 00000101.
Поскольку компьютер видит только единицы и нули, всю входящую информацию он сначала преобразует в понятную ему форму и только потом выполняет вычисления. Чтобы код обрабатывался быстрее, можно сразу обращаться к компьютеру на его языке. Побитовые операторы Java позволяют работать с двоичным представлением любого числа и выполнять операции без перевода, поэтому они очень быстрые. Обычно их используют для работы со сложными данными: картинками, видео или музыкой, например, чтобы сделать фотографию чёрно-белой или увеличить громкость музыки.
Побитовые операторы работают по битам — проходятся по всей цепочке, перебирая значения одно за другим. Разберёмся, как именно они это делают.
Побитовое НЕ — это унарный оператор отрицания. Он применяется только к одной цепочке битов, проходится по каждому её элементу и меняет значение на противоположное. Например, ∼101 = 010. Но это не то же самое, что поставить перед числом знак минус. Побитовое НЕ не делает число отрицательным.
Побитовое И — это бинарный оператор, который применяется к двум цепочкам битов. Сначала он обращается к первому биту в каждой из цепочек, потом ко второму и так далее. А результатом этого выражения будет третья цепочка.
Работает этот оператор по тому же принципу, что и логическое И. Его ещё называют побитовым умножением. Только в том случае, когда в обеих цепочках стоит единица, программа вернёт единицу. Во всех остальных случаях результатом будет ноль.
111 & 000 = 0
111 & 001 = 001
111 & 010 = 010
Побитовое ИЛИ называют побитовым сложением. Этот оператор делает то же самое, что и логическое ИЛИ, только применяется не к отдельным величинам, а к цепочкам битов. 111 = 011
Сдвиг вправо выполняется по формуле x >> y, где x — цепочка битов, а y — количество шагов, на которое её нужно сдвинуть.
Разберём принцип действия этого оператора на примере: 101 >> 1 = 010.
Крайний бит справа выходит за границу диапазона и исчезает. Крайний бит слева повторяет своего предшественника: на место единицы встаёт единица, на место нуля — ноль. Поскольку этот бит, отвечающий за знак, не меняется, положительное число остаётся положительным, отрицательное — отрицательным
Если проводить параллель с математикой, то при каждом сдвиге цепочки битов на один шаг вправо выполняется целочисленное деление исходного числа на два. Для наглядности переведём операнды в десятичную систему счисления. Двоичной записи 101 соответствует число 5. Оператор делит его на два, отбрасывает остаток и возвращает число 2, которому в двоичной системе счисления соответствует 010. Всё сходится!
Сдвиг вправо с заполнением нулями отличается от предыдущего оператора лишь тем, что все освободившиеся ячейки слева он всегда заполняет нулями. Если до выполнения операции старшим битом была единица, на её место встанет ноль, знак числа изменится и из отрицательного оно превратится в положительное.
Сдвиг влево выполняется по тому же принципу, что и сдвиг вправо, только в обратную сторону. Чтобы посмотреть, как это работает, сдвинем операнд из примера выше влево: 101 << 1 = 1010.
Аналогом этой операции в математике будет умножение исходного числа на два. Если переведём исходное число и результат операции в десятичную систему, получим числа 5 и 10. То есть выражение 101 << 1 = 1010 в десятичной системе счисления можно было бы записать как 5 * 2 = 10
Сдвиг того же числа на два шага влево вернёт результат — 10100. В десятичной системе счисления ему соответствует число 20. Всё выражение можно было бы записать в две итерации: 5 * 2 = 10 и 10 * 2 = 20.
На первых порах с побитовыми операторами Java лучше обращаться предельно внимательно:
● Они меняют знак числа, превращая отрицательное в положительное.
● При переводе результатов вычисления из двоичной системы в десятичную результат может получиться неочевидным.
Прочие операторы
Тернарный оператор или оператор условия Java
Условных операторов в Java нет. Конструкции if и if-else, которые в других языках программирования называют условными операторами, в Java относятся к инструкциям.
Но иногда программистам хочется добавить в выражение условие. Специально для этого они придумали тернарный оператор — ?:, который можно считать аналогом инструкции if.
Например, в выражении a ? 10 : 11 задано условие: если а — true, программа вернёт 10, если false — 11. То есть всё будет зависеть от значения переменной а, ей можно присвоить любое числовое значение и даже целое выражение. Например, a = 1==2. В этом случае тернарный оператор вернёт 11— единица не равна двойке, а значит, а — false.
Этот оператор популярен среди опытных разработчиков, но новичкам лучше его не использовать, чтобы не запутаться.
Оператор instanceof
Это простой оператор, который позволяет проверить тип входящей переменной и возвращает булевое значение — true или false. Например, с помощью выражения x instanceof Integer программист задаёт компьютеру вопрос: эта переменная относится к классу Integer — да или нет? Оператор полезен, когда значение x программа получает извне.
Укороченные операторы
Для упрощения кода разработчики придумали использовать укороченные операторы Java. Они позволяют провести вычисление и присвоить его результат переменной всего одной командой. Например, выражение a = a + 2 можно записать короче: a += 2. Означать эти выражения будут одно и то же. Подобный фокус можно проделать с любыми побитовыми и логическими операторами Java, используя общую формулу.
Инкремент и декремент
Иногда эти операторы в Java относят к арифметическим, но правильнее рассматривать их отдельно.
Инкремент и декремент программисты ввели для простоты записи. Они не требуют присваивания и позволяют сразу увеличить или уменьшить на единицу ту переменную, к которой относятся
Декремент и инкремент бывают префиксными — стоят перед переменной, а бывают постфиксными — после переменной. Для самой переменной разницы нет никакой: ++a и a++ увеличивают её на единицу. Однако выражения b = ++a и b = a++ будут отличаться по смыслу. В первом случае b присвоится значение ++a, а во втором — только a. Сама переменная a увеличится на единицу уже после того, как её значение будет присвоено b. Поэтому новичкам рекомендуют вместо инкремента и декремента использовать аналоги. Например, заменить a++ на a += 1 или даже на a = a + 1.
Приоритеты операторов Java
В языке Java последовательность выполнения операций выстроена так, чтобы соблюсти правила арифметики. Сложение идёт после умножения, умножение в одну цепочку выполняется строго слева направо, а выражение, взятое в круглые скобки, имеет наивысший приоритет. Рассмотрим приоритетность выполнения операторов Java в таблице.
Совет эксперта
Пётр Кушнир
Чтобы до конца понять суть операторов Java, придётся параллельно разбираться с типами данных и двоичной арифметикой. Всё это поможет понять, как устроены вычисления выражений с операторами «под капотом». Благодаря этому разработчик научится писать корректный код и понимать, что написали другие.
Статью подготовили:
Пётр Кушнир
Яндекс Практикум
Автор курса
«Java-разработчик»
Яндекс Практикум
Редактор
Полина Овчинникова
Яндекс Практикум
Иллюстратор
Поделиться
Читать также:
В Java всегда весна: почему фреймворк Spring считается самым популярным у Java-разработчиков
Читать статью
Java-разработчик: плюсы и минусы профессии, как стать и сколько зарабатывает
Читать статью
Основы программирования на Java
Основы программирования на Java
ОглавлениеВВЕДЕНИЕОСНОВНЫЕ ПОНЯТИЯ 1. ПЕРЕМЕННЫЕ 2. ТИПЫ 2.1. Простые типы 2.1.1. Числовые типы 2.1.2. Символы 2.1.3. Тип boolean 2.2. Приведение типов 3. МАССИВЫ 3.1. Многомерные массивы 4. ОПЕРАТОРЫ 4.1. Арифметические операторы 4.1.1. Оператор деления по модулю 4.1.2. Арифметические операторы присваивания 4.1.3. Инкремент и декремент 4.2. Целочисленные битовые операторы и операторы отношений 4.4. Булевы логические операторы 4.5. Тернарный оператор if-then-else 4.6. Приоритеты операторов 5. УПРАВЛЕНИЕ ВЫПОЛНЕНИЕМ ПРОГРАММЫ 5.1. Условный оператор if-else 5.2. Опреатор break 5.3. Оператор switch 5.4. Оператор return 6. ЦИКЛЫ 6.1. Цикл while 6.2. Цикл do-while 6.3. Цикл for 6.4. Оператор continue ОБЪЕКТНО-ОРИЕНТИРОВАННОЕ ПРОГРАММИРОВАНИЕ НА JAVA 7. КЛАССЫ 7.1. Переменные класса 7.2. Оператор new 7.3. Объявление методов 7.4. Вызов метода 7.6. Конструкторы 7.7. Совмещение методов 7.8. Ссылка this 7.9. Наследование 7.10. Ссылка super 7.11. Замещение методов 7.12. Динамическое назначение методов 7.13. Директива final 7.14. Деструкторы 7.15. Статические методы Директива final, деструкторы и статические методы 7.16. Абстрактные классы 8. ПАКЕТЫ И ИНТЕРФЕЙСЫ 8.1. Пакеты 8.2. Интерфейсы 9. ОБРАБОТКА ИСКЛЮЧЕНИЙ 9. 1. Основы механизма исключений 9.2. Типы исключений 9.3. Неперехваченные исключения 9.5. Несколько разделов catch 9.6. Вложенные операторы try 9.7. Оператор throw 9.8. Оператор throws Операторы throw и throws 9.9. Оператор finally 10. МНОГОПОТОЧНОЕ ПРОГРАММИРОВАНИЕ 10.1. Модель легковесных процессов в Java 10.2. Подпроцесс 10.3. Интерфейс Runnable 10.4. Приоритеты подпроцессов 10.5. Синхронизация 10.6. Методы программного интерфейса легковесных процессов 11. ВВОД/ВЫВОД 11.1. Работа с файлами 11.2. Каталоги Классы InputStream и OutputStream 11.3. Класс InputStream 11.4. Класс OutputStream Файловый поток FilelnputStream и FileOutputStream 11.5. Файловый поток FilelnputStream 12. ПРОГРАММИРОВНИЕ ГРАФИЧЕСКИХ ПОЛЬЗОВАТЕЛЬСКИХ ИНТЕРФЕЙСОВ 12.1. Компоненты 12.2. Класс Container 12.3. Класс Canvas 12.4. Класс Label 12. 5. Класс Button 12.6. Класс Checkbox 12.7. Класс CheckboxGroup 12.8. Класс Choice 12.9. Класс List 12.10. Класс Scrollbar 12.11. Класс TextField 12.12. Класс TextArea 12.13. Стратегии размещения компонентов 12.14. Программирование окон – Window 12.15. Программирование меню 12.16. Модель обработки событий от компонентов ЗАКЛЮЧЕНИЕ |
Каков в Java логический «порядок операций»?
Приоритет логического оператора оценки логики Java
Вопрос задан 14.04.19Возьмем простой пример объекта `Кошка`. Я хочу быть уверенным, что «ненулевой» `cat` либо оранжевый, либо серый. if(cat != null && cat.getColor() == «оранжевый» || cat.getColor() == «серый») { //делаем что-то } Я считаю, что сначала идет И, затем ИЛИ. Я немного нечеткий, поэтому вот мои вопросы: 1. Может ли кто-нибудь объяснить мне это заявление, чтобы я был уверен, что понимаю, что происходит? 2.
Подписаться І 2
Подробнее
Отчет
1 ответ эксперта
Лучший Новейшие Самый старыйАвтор: Лучшие новыеСамые старые
Дэвид С. ответил 16.04.19
Репетитор
5,0 (829)
Генеральный директор/ведущий программист/преподаватель Java с опытом работы более 8 лет
Об этом репетиторе ›
Об этом репетиторе ›
Вы совершенно правы! И (&&) действительно стоит первым, за ним следует ИЛИ (||).
Пошаговая инструкция:
Сначала вычисляется cat != null && cat. getColor() == «orange». (Хотя следует отметить, что для сравнения строк, а также любого типа данных объекта вы должны использовать .equals() вместо ==. Таким образом, это будет cat.getColor().equals(«orange») и cat. getColor().equals(«grey») вместо этого 😊)
Затем оператор ИЛИ оценивается по сравнению с результатом предыдущего оператора И.
Однако это конкретное логическое выражение не будет работать должным образом. Это потому, что вы проверяете, не является ли кошка нулевой и является ли она оранжевой, ИЛИ является ли кошка серой. Невозможно выйти из оператора if, если кот действительно нулевой, прежде чем проверять, является ли он серым. Это может вызвать исключение NullPointerException.
Чтобы исправить это, вам нужно заключить в круглые скобки последние две трети оператора, чтобы он сначала проверял, не является ли кошка нулевым, а ЗАТЕМ проверял, является ли он оранжевым или серым.
Например, это будет выглядеть так:
if(cat != null && (cat. getColor().equals(«оранжевый» ) || cat.getColor().equals(«серый»)))
{
//stuff
}
Если вы где-нибудь добавили круглые скобки, они будут оцениваться перед И и ИЛИ. Для Java, как и для большинства других языков, порядок операций для логического оператора следующий:
- ! НЕ
- () Скобки
- && И
- || ИЛИ
Надеюсь, это поможет!
Голосовать за 0 голос против
Подробнее
Отчет
Все еще ищете помощи? Получите правильный ответ, быстро.
Задайте вопрос бесплатно
Получите бесплатный ответ на быстрый вопрос.
Ответы на большинство вопросов в течение 4 часов.
ИЛИ
Найдите онлайн-репетитора сейчас
Выберите эксперта и встретьтесь онлайн. Никаких пакетов или подписок, платите только за то время, которое вам нужно.
концепций — логический размер не определен в java: почему?
Есть несколько понятий, которые следует разобрать:
- сам язык программирования Java, который является текстовым языком программирования,
- байт-код виртуальной машины Java и формат файла класса , который представляет собой двоичную скомпилированную кодировку исходного кода исходного языка Java и используется в качестве формата файла обмена для хранения, загрузки и совместного использования объектного кода Java,
- конкретная реализация виртуальной машины Java , которая может быть интерпретатором, хотя часто вместо этого является реализацией на основе JIT,
- JIT генерирует машинный код, который работает непосредственно на аппаратном процессоре.
Java, язык программирования , не определяет размер концепции примитивных типов, потому что (в отличие от C/C++) нет оператора sizeof
: размеры не наблюдаются через языковые конструкции, поэтому язык не нуждается чтобы определить их.
Как указывает @Ralf, язык Java определяет диапазон примитивных типов, что очень важно для программиста, поскольку эти диапазоны можно наблюдать с помощью конструкций внутри языка.
Язык определяет возможность инструментирования, которая позволяет запрашивать размер объекта, но (1) это требует инструментирования, (2) предоставляет только оценку и (3) этот запрос не применяется к примитивным типам или локальным переменные.
JVM использует 32-битную ячейку стека, используемую для хранения локальных переменных, аргументов метода и значений выражений. Примитивы размером менее 1 ячейки дополняются, примитивы размером более 32 бит (длинные и двойные) занимают 2 ячейки
Заполняющая цитата говорит о деталях формата файла класса JVM, который используется в качестве механизма обмена (в отличие от языка Java и реализации JVM). Хотя то, что он говорит, справедливо для абстрактной машины и байт-кода JVM, это не обязательно должно выполняться для машинного кода JIT.
Заполняющая цитата также ограничивается обсуждением локальных переменных/параметров/выражений, которые обычно размещаются в стеке (например, auto или Automatics в C/C++), и не обсуждает объекты/массивы.
Фактический размер таких автоматических переменных почти никогда не является проблемой (например, для производительности или для места).
Частично это связано с тем, что базовые аппаратные ЦП более естественно работают с большими битами (например, 32 или 64), а не с 1 битом. Даже 8- или 16-битные размеры обычно не быстрее, чем 32-битные, а иногда для обработки 8-битной обработки требуется дополнительная инструкция или две для работы с более широкими регистрами набора аппаратных инструкций.
И еще одна причина — ограниченное использование локальных переменных — они используются непосредственно кодом и только кодом и, таким образом, практически не подвержены проблемам масштабирования — в частности, по сравнению с объектами и массивами, которые используются структурами данных потенциально любого масштаба.
(Мы можем рассматривать рекурсию как масштабирование локальных переменных, поэтому большие локальные переменные в рекурсивных подпрограммах рискуют переполниться стеком раньше.)
Однако размеры объектов могут иметь большое значение, если количество экземпляров велико, а также, размеры элементов массива могут иметь значение при наличии большого количества элементов.
Означает ли это, что даже типы данных byte/char/short primitiva также занимают 32 бита, хотя их размер определен как 8/16/16 бит?
Для местных, может быть, может и не зависит от JIT.
Для объектов в рамках механизма байт-кода и файла класса JVM доступ к полям осуществляется напрямую посредством их идентификации, и понятие «ячейки» отсутствует, в то время как с переменными (локальными и параметрическими) существует.
Реализация JVM (включая ее JIT) может изменять порядок полей внутри реализации (например, на уровне машинного кода), поэтому два 16-битных поля могут занимать одно и то же 32-битное слово, даже если они не были объявлены рядом в исходный код; это снижает накладные расходы, вызванные заполнением, необходимым для поддержания выравнивания.