Бинарные операторы в Java

    В OTUS скоро стартует новая профессиональная программа по подготовке к сертификации Oracle Java Programmer (OCAJP). Приглашаем вас на бесплатный Demo-урок «Типы данных Java: Идентификаторы и примитивы» и публикуем статью Владислава Родина — руководителя группы разработки, преподавателя в МФТИ и foxminded.



    Введение


    Сертификация OCA (Oracle Certified Associate Java SE8 Programmer) предлагает ряд необычных заданий, проверяющих глубокое понимание принципов работы языка программирования Java. Целый блок посвящен выражениям, циклам и оператором. Про последние мы сегодня и поговорим.

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


    Оператор принимает на вход аргументы и возвращает некоторые значения. Выделяют унарные, бинарные и тернарные операторы. Например, !false — унарный, a + b — бинарный, а? : — является единственным оператором, принимающим на вход три аргумента.

    Первое, что необходимо помнить, это приоритет выполнения операторов:

    1. Пост-унарные операторы: exception++ и exception--
    2. Пре-унарные операторы: ++exception и --exception
    3. Остальные унарные операторы: +, -, !
    4. Умножение, деление, взятие остатка: *, /, %
    5. Сложение и вычитание: +, -
    6. Операторы битового сдвига: <<, >>, >>>
    7. Операторы сравнения: <, >, <=, >=, instanceof
    8. Операторы равенства-неравенства: ==, !=
    9. Логические операторы: &, |, ^
    10. Short-circuit логические операторы: &&, ||
    11. Тернарный оператор: boolean expression? expression1: expres-
      sion2
    12. Операторы присваивания: =, +=, -=, *=, /=, %=, &=, ^=, !=, <<=, >>=, >>>=

    Работа с бинарными арифметическими операторами


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

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


    К арифметическим операторам относятся операторы сложения, вычитания, умножения и взятия остатка. Как я уже сказал, при вычислении необходимо помнить приоритет операторов:

    int x = 2 * 5 + 3 * 4 — 8 = 10 + 12 — 8 = 14;

    Также надо помнить, что приоритет выполнения может изменяться скобками (вначале вычисляется выражение в скобках):

    int x = 2 * ((5 + 3) * 4 – 8) = 2 * (8 * 4 – 8) = 2 * (32 – 8) = 2 * 24 = 48;

    Новички могут путать операторы целочисленного деления (/) и взятия модуля (%):

    System.out.print(9 / 3); // Outputs 3
    System.out.print(9 % 3); // Outputs 0
    
    System.out.print(10 / 3); // Outputs 3
    System.out.print(10 % 3); // Outputs 1
    
    System.out.print(11 / 3); // Outputs 3
    System.out.print(11 % 3); // Outputs 2
    
    System.out.print(12 / 3); // Outputs 4
    System.out.print(12 % 3); // Outputs 0
    

    Преобразование чисел


    Если аргументы бинарного оператора числовые и разные, Java применяет преобразования типов по следующим правилам:

    1. Если два аргумента относятся к разным типам данных, то Java преобразует аргумент менее вместительного типа к аргументу более вместительного типа
    2. Если один аргумент относится к целочисленному типу, а другой к вещественному, то Java преобразует значение целочисленного типа к вещественному типу
    3. Независимо от типов аргументов, Java вначале преобразует менее вместительные целочисленные типы (byte, short, char) к типу int
    4. После приведения аргументов к одному типу, Java вернет результат того же типа, которым обладают аргументы после приведения

    Пример 1

    Какого типа будет результат выполнения умножения x * y?

    int x = 1;
    long y = 33;
    

    Согласно первому правилу, x будет преобразован к типу long, а затем будет возвращен результат того же типа.

    Пример 2

    Какого типа будет результат выполнения сложения x + y?

    double x = 39.21;
    float y = 2.1;
    

    Здесь в лучших традициях сертификации нас подстерегает ловушка: 2.1 — это double, а 2.1f — это float. Попытка записать значение типа double в переменную типа float без явного преобразования приводит к ошибке компиляции в Java.

    Пример 3

    Какого типа будет результат выполнения сложения x + y?

    double x = 39.21;
    float y = 2.1f;
    

    По аналогии с примером 1, float будет преобразован к double, а затем будет возвращен результат типа double.

    Пример 4

    Какого типа будет результат выполнения деления x / y?

    short x = 10;
    short y = 3;
    

    Согласно правилу 3 оба аргумента перед выполнением деления будут приведены к int, а потом по правилу 4 будет возвращен int. Ответ вовсе не short!

    Пример 5

    Какого типа будет результат выполнения операции x * y / z?

    short x = 14;
    float y = 13;
    double z = 30;
    

    Согласно всем правилам выше вначале x будет преобразован к int'у. Затем выполняется операция умножения x (int) и y (float): x будет преобразован ко float, и результат будет принадлежать типу float. Потом выполняется float / double, поэтому float будет преобразован к double, и будет возвращен double.

    Интересно развиваться в данном направлении? Посмотрите программу курса «Подготовка к сертификации Oracle Java Programmer (OCAJP)»!
    OTUS. Онлайн-образование
    Цифровые навыки от ведущих экспертов

    Комментарии 2

      +1
      Кажется название статьи не совсем соответствует содержанию. В статье речь идет и о преобразованиях между примитивными типами, и о приоритетов операторов (не только бинарных). И насчет правил авторасширения типов — возьмите правила с официальной документации. На мой взгляд, приведенные вами правила авторасширения типов очень нечетки.
        0

        Лайфхак для подготовки — берёте Java Language Specification по той версии, по которой будет экзамен (сейчас, кажется, 11?), и по нему готовитесь.


        У меня вот от этой статьи стойкие флешбеки к JLS, будто сама статья — это переведённая и чуть локализованная версия JLS. Ничего в целом не имею против, но так как сам экзамен всё равно на ненашем, лучше и готовиться по первоисточнику.

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

        Самое читаемое