Java приоритет бинарных операторов

Ошибка Java «неверные типы операндов для бинарного оператора»

Java предоставляет набор побитовых операторов . Эти операторы позволяют нам удобно манипулировать отдельными битами числа.

Однако, когда мы сравниваем результат побитовой операции, мы можем попасть в распространенную ловушку.

В этом кратком руководстве мы обсудим, почему мы можем столкнуться с ошибкой времени компиляции Java «неверные типы операндов для бинарного оператора» и как решить эту проблему.

2. Введение в проблему​

Как обычно, разберемся в проблеме на примере. Но сначала рассмотрим простой метод:

 public void checkNumber()    ListInteger> intList = Arrays.asList(1, 2, 3, 4, 5, 6, 7);   intList.forEach(i ->    if (i & 1 == 1)    System.out.println(i + " is odd.");   > else    System.out.println(i + " is even.");   >   >);   > 

Как мы видим, метод checkNumber проходит через intList , проверяет и выводит, является ли каждое число четным или нечетным.

Отметим, что логика проверки на нечетность в методе реализована нестандартно: i % 2 == 1 . Вместо этого мы выполняем побитовую операцию И (&) над целым числом ( i ) и 1. Если результат равен 1, мы знаем, что целое число i является нечетным числом: i & 1 ==1 .

Однако, когда мы пытаемся протестировать описанный выше метод, код неожиданно не компилируется:

 java: bad operand types for binary operator '&'   first type: java.lang.Integer  second type: boolean 

Далее давайте разберемся, в чем причина проблемы и как ее решить.

3. Понимание приоритета операторов Java​

Во-первых, сообщение об ошибке довольно простое. В нем говорится, что мы пытаемся выполнить побитовое И для логического типа и целочисленного типа.

Однако это странно, поскольку мы буквально написали « i & 1 » в коде. Почему компилятор считает, что логический тип участвует в побитовой операции И?

Это связано с тем, что оператор « == » имеет более высокий приоритет, чем оператор « & ». То есть выражение « i & 1 == 1 » такое же, как « i & (1 == 1) ». Таким образом, у нас есть « i & true (boolean) ».

Теперь мы можем спросить: «Хорошо, == имеет более высокий приоритет, чем & . Но почему ‘ i % 2 == 1 ‘ работает так, как ожидалось?»

Чтобы ответить на этот вопрос, нам нужно более подробно рассмотреть правило приоритета операторов Java.

Java предоставляет довольно много операторов . На практике мы часто используем разные операторы вместе. Поэтому важно понимать приоритет операторов Java. В противном случае мы можем получить неожиданный результат.

Далее, давайте посмотрим на правило приоритета операторов Java (чем выше в таблице стоит оператор, тем выше его приоритет):

 | Операторы | Приоритет |  | постфикс | `выражение ++ выражение —` |  | унарный | `++ выражение — выражение + выражение — выражение ~ !` |  | мультипликативный | `* / %` |  | добавка | `+ –` |  | сдвиг | `> >>>` |  | относительный | ` < >= instanceof` |  | равенство | `== !=` |  | побитовое И | `&` |  | побитовое исключающее ИЛИ | `^` |  | побитовое включительно ИЛИ | `|` |  | логическое И | `&&` |  | логическое ИЛИ | `||` |  | троичный | `? :` |  | назначение | `= += -= *= /= %= &= ^= |= <>= >>>=` | 

Как видно из приведенного выше списка, оператор по модулю (%) имеет более высокий приоритет, чем оператор равенства ( == ) . С другой стороны, побитовый оператор И (&) находится ниже оператора равенства (==) в таблице.

Вот почему « i % 2 == 1 » работает, как и ожидалось, а « i & 1 == 1 » — нет.

В нашем примере мы столкнулись с ошибкой времени компиляции. Таким образом, мы можем обнаружить проблему относительно рано. Однако представьте, что некоторая реализация с ошибкой приоритета оператора компилируется, но выдает неверный результат. Поиск реальной причины проблемы может занять у нас много времени.

Итак, стоит помнить о правиле приоритета операторов Java.

4. Решение проблемы​

Теперь, когда мы понимаем причину проблемы, ее устранение не является сложной задачей. Нам просто нужно добавить круглые скобки к операции побитового И:

После исправления, если мы запустим метод еще раз, мы увидим, что компилятор больше не жалуется, и мы получим ожидаемый результат:

 1 is odd.  2 is even.  3 is odd.  4 is even.  5 is odd.  6 is even.  7 is odd. 

5. Вывод​

В этой быстрой статье мы проанализировали ошибку компиляции «неправильные типы операндов для бинарного оператора» на примере операции побитового И.

Кроме того, мы обсудили правило приоритета операторов Java.

Наконец, мы исправили проблему.

Источник

Операторы

Java предоставляет богатый набор операторов для управления переменными. Все операторы Java можно разделить на следующие группы:

  • арифметические операторы;
  • операторы сравнения;
  • побитовые операторы;
  • логические операторы;
  • операторы присваивания;
  • прочие операторы.

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

Арифметические операторы — используются в математических выражениях таким же образом, как они используются в алгебре. Предположим, целая переменная A равна 10, а переменная B равна 20. В следующей таблице перечислены арифметические операторы в Java:

Оператор Описание Пример
+ Складывает значения по обе стороны от оператора A + B даст 30
Вычитает правый операнд из левого операнда A — B даст -10
* Умножает значения по обе стороны от оператора A * B даст 200
/ Оператор деления делит левый операнд на правый операнд B / A даст 2
% Делит левый операнд на правый операнд и возвращает остаток B % A даст 0
++ Инкремент — увеличивает значение операнда на 1 B++ даст 21
Декремент — уменьшает значение операнда на 1 B— даст 19

Пример

Следующий простой пример показывает программно арифметические операторы. Скопируйте и вставьте следующий java-код в файл test.java, скомпилируйте и запустить эту программу:

public class Test < public static void main(String args[]) < int a = 10; int b = 20; int c = 25; int d = 25; System.out.println("a + b = " + (a + b)); System.out.println("a - b = " + (a - b)); System.out.println("a * b = " + (a * b)); System.out.println("b / a = " + (b / a)); System.out.println("b % a = " + (b % a)); System.out.println("c % a = " + (c % a)); System.out.println("a++ = " + (a++)); System.out.println("b-- = " + (a--)); // Проверьте разницу в d++ и ++d System.out.println("d++ = " + (d++)); System.out.println("++d dos">a + b = 30 a - b = -10 a * b = 200 b / a = 2 b % a = 0 c % a = 5 a++ = 10 b-- = 11 d++ = 25 ++d = 27 

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

Есть следующие операторы сравнения, поддерживаемые на языке Java. Предположим, переменная A равна 10, а переменная B равна 20. В следующей таблице перечислены реляционные операторы или операторы сравнения в Java:

Оператор Описание Пример
== Проверяет, равны или нет значения двух операндов, если да, то условие становится истинным (A == B) — не верны
!= Проверяет, равны или нет значения двух операндов, если значения не равны, то условие становится истинным (A != B) — значение истинна
> Проверяет, является ли значение левого операнда больше, чем значение правого операнда, если да, то условие становится истинным (A > B) — не верны
= Проверяет, является ли значение левого операнда больше или равно значению правого операнда, если да, то условие становится истинным (A >= B) — значение не верны
> (сдвиг вправо) Бинарный оператор сдвига вправо. Значение правых операндов перемещается вправо на количество бит, заданных левых операндом. A >> 2 даст 15, который является 1111
>>> (нулевой сдвиг вправо) Нулевой оператор сдвига вправо. Значение левых операндов перемещается вправо на количество бит, заданных правым операндом, а сдвинутые значения заполняются нулями. A >>> 2 даст 15, который является 0000 1111

Пример

Следующий простой пример показывает, программно побитовые операторы в Java. Скопируйте и вставьте следующий java-код в файл test.java, скомпилируйте и запустить эту программу:

public class Test < public static void main(String args[]) < int a = 60; /* 60 = 0011 1100 */ int b = 13; /* 13 = 0000 1101 */ int c = 0; c = a & b; /* 12 = 0000 1100 */ System.out.println("a & b = " + c ); c = a | b; /* 61 = 0011 1101 */ System.out.println("a | b = " + c ); c = a ^ b; /* 49 = 0011 0001 */ System.out.println("a ^ b = " + c ); c = ~a; /*-61 = 1100 0011 */ System.out.println("~a a > 2 a >>> 2 html">a & b = 12 a | b = 61 a ^ b = 49 ~a = -61 a > 15 a >>> 15 

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

Предположим, логическая переменная A имеет значение true, а переменная B хранит false. В следующей таблице перечислены логические операторы в Java:

Оператор Описание Пример
&& Называется логический оператор «И». Если оба операнда являются не равны нулю, то условие становится истинным (A && B) — значение false
|| Называется логический оператор «ИЛИ». Если любой из двух операндов не равен нулю, то условие становится истинным (A || B) — значение true
! Называется логический оператор «НЕ». Использование меняет логическое состояние своего операнда. Если условие имеет значение true, то оператор логического «НЕ» будет делать false !(A && B) — значение true

Пример

Следующий простой пример показывает, программно логические операторы в Java. Скопируйте и вставьте следующий java-код в файл test.java, скомпилируйте и запустить эту программу:

public class Test < public static void main(String args[]) < boolean a = true; boolean b = false; System.out.println("a && b = " + (a&&b)); System.out.println("a || b = " + (a||b) ); System.out.println("!(a && b) dos">a && b = false a || b = true !(a && b) = true 

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

Существуют следующие операторы присваивания, поддерживаемые языком Java:

Оператор Описание Пример
= Простой оператор присваивания, присваивает значения из правой стороны операндов к левому операнду C = A + B, присвоит значение A + B в C
+= Оператор присваивания «Добавления», он присваивает левому операнду значения правого C += A, эквивалентно C = C + A
-= Оператор присваивания «Вычитания», он вычитает из правого операнда левый операнд C -= A, эквивалентно C = C — A
*= Оператор присваивания «Умножение», он умножает правый операнд на левый операнд C * = A эквивалентно C = C * A
/= Оператор присваивания «Деление», он делит левый операнд на правый операнд C /= A эквивалентно C = C / A
%= Оператор присваивания «Модуль», он принимает модуль, с помощью двух операндов и присваивает его результат левому операнду C %= A, эквивалентно C = C % A
>= Оператор присваивания «Сдвиг вправо» C >>= 2, это как C = C >> 2
&= Оператор присваивания побитового «И» («AND») C &= 2, это как C = C & 2
^= Оператор присваивания побитового исключающего «ИЛИ» («XOR») C ^= 2, это как C = C ^ 2
|= Оператор присваивания побитового «ИЛИ» («OR») C |= 2, это как C = C | 2

Пример

Следующий простой пример показывает, программно логические операторы в Java. Скопируйте и вставьте следующий java-код в файл test.java, скомпилируйте и запустить эту программу:

public class Test < public static void main(String args[]) < int a = 10; int b = 20; int c = 0; c = a + b; System.out.println("c = a + b = " + c ); c += a ; System.out.println("c += a = " + c ); c -= a ; System.out.println("c -= a = " + c ); c *= a ; System.out.println("c *= a = " + c ); a = 10; c = 15; c /= a ; System.out.println("c /= a = " + c ); a = 10; c = 15; c %= a ; System.out.println("c %= a c >= 2 c >>= a = " + c ); c &= a ; System.out.println("c &= 2 = " + c ); c ^= a ; System.out.println("c ^= a = " + c ); c |= a ; System.out.println("c |= a dos">c = a + b = 30 c += a = 40 c -= a = 30 c *= a = 300 c /= a = 1 c %= a = 5 c >= 2 = 5 c >>= 2 = 1 c &= a = 0 c ^= a = 10 c |= a = 10

Прочие операторы

Есть несколько других операторов, поддерживаемых языком Java.

Тернарный оператор или условный оператор (?:)

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

переменная x = (выражение) ? значение if true : значение if false

Пример

Будет получен следующий результат:

Значение b: 30 Значение b: 20

Оператор instanceof

Оператор instanceof — проверяет, является ли объект определенного типа (типа класса или типа интерфейса) и используется только для переменных ссылочного объекта. Оператор instanceof записывается в виде:

(Переменная ссылочного объекта) instanceof (класс/тип интерфейса)

Примеры

Если переменная ссылочного объекта в левой части оператора проходит проверку для класса/типа интерфейса на правой стороне, результатом будет значение true. Ниже приведен пример и описание оператора instanceof:

Будет получен следующий результат:

Этот оператор по-прежнему будет возвращать значение true, если сравниваемый объект является совместимым с типом на право назначения. Ниже приводится еще один пример:

class Vehicle <> public class Car extends Vehicle < public static void main(String args[])< Vehicle a = new Car(); boolean result = a instanceof Car; System.out.println( result ); >>

Будет получен следующий результат:

Приоритет операторов в Java

Приоритет операторов определяет группирование терминов в выражении. Это влияет как вычисляется выражение. Некоторые операторы имеют более высокий приоритет, чем другие; например оператор умножения имеет более высокий приоритет, чем оператор сложения:

Например, x = 7 + 3 * 2. Здесь x присваивается значение 13, не 20, потому что оператор «*» имеет более высокий приоритет, чем «+», так что сначала перемножается «3 * 2», а затем добавляется «7».

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

Категория Оператор Ассоциативность
Постфикс () [] . (точка) Слева направо
Унарный ++ — — ! ~ Справа налево
Мультипликативный * / % Слева направо
Аддитивный + — Слева направо
Сдвиг >> >>> >= >= Справа налево
Запятая , Слева направо

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

Источник

Читайте также:  Margin from border css
Оцените статью