Пріоритет і асоціативність операторів

Пріоритетом (precedence) оператора називається порядок, в якому він виконується по відношенню до інших операторів Різні оператори мають різні пріоритети Наприклад, пріоритет умовних операторів вище, ніж у логічних, тому ви можете написати

if (i &gt&gt= min &amp&amp i &lt&lt= max)

process(i)

не сумніваючись у порядку виконання операторів Оскільки * (множення) має більш високий пріоритет, ніж – (віднімання), значення виразу

5 * 3 — 3

дорівнює 12, а не нулю Пріоритет операторів можна змінити за допомогою дужок наприклад, якби в попередньому виразі вам було потрібно отримати саме нуль, то для цього достатньо поставити дужки:

5 * (3 — 3)

Коли два оператора з однаковими пріоритетами виявляються поряд, порядок їх виконання визначається асоціативністю операторів Оскільки + (додавання) відноситься до ліво-асоціативним операторам, вираз

a + b + c

еквівалентно наступному: (a + b) + c

Нижче всі оператори перераховуються в порядку убування пріоритетів Всі вони є бінарними, за винятком унарних операторів, операторів створення і перетворення типу (також унарних) і тернарного умовного оператора Оператори з однаковим пріоритетом наведені в одному рядку таблиці:

постфіксні оператори [] (Параметри) expr + + expr-унарні оператори + + expr-expr + expr-expr ~ створення і перетворення типу new (тип) expr

оператори множення / ділення * /% оператори додавання / віднімання + – оператори зсуву << >> >>>

оператори відносини < > > = <= Instanceof

оператори рівності == = поразрядное І & поразрядное виключає АБО ^ поразрядное включає АБО | логічне І && логічне АБО | | умовний оператор:

оператори присвоювання = + = – = * = / =% = >> = << = >>> = & = ^ = | =

Всі бінарні оператори, за винятком операторів присвоювання, є ліво-асоціативними Оператори присвоювання є право-асоціативними – Іншими словами, вираз a = b = c еквівалентно a = (b = c)

Пріоритет може змінюватися за допомогою дужок У виразі x + y * z спочатку y множиться на z, після чого до результату додається x, тоді як у виразі (x + y) * z спочатку обчислюється сума x і y, а потім результат множиться на z

Присутність дужок часто виявляється необхідним у тих виразах, де використовується поразрядное логіка або присвоювання здійснюється всередині логічного виразу Як приклад розглянемо наступний фрагмент:

while ((v = streamnext()) = null)

processValue(v)

Пріоритет операторів присвоювання нижче, ніж в операторів рівності без дужок наш приклад був би рівнозначний наступного:

while (v = (streamnext () = null)) / / НЕВІРНО

processValue(v)

що, ймовірно, відрізняється від очікуваного порядку обчислень Крім того, конструкція без дужок, швидше за все, виявиться невірною – вона буде працювати лише в малоймовірному випадку, якщо v має тип boolean

Пріоритет порозрядних логічних операторів &, ^ і | також може викликати деякі труднощі Бінарні порозрядні оператори в складних виразах теж слід укладати в дужки, щоб полегшити читання вираження і забезпечити правильність обчислень

У цій книзі дужки вживаються досить рідко – лише в тих випадках, коли без них зміст виразу буде неочевидним Пріоритети операторів є важливою частиною мови і їх потрібно знати Багато програмістів схильні зловживати дужками Намагайтеся не користуватися дужками там, де без них можна обійтися – перевантажена дужками програма стає нелегкою і починає нагадувати LISP, не купуючи, однак, жодного з достоїнств цієї мови

511 Порядок обчислень

Мова Java гарантує, що операнди в операторах обчислюються зліва направо Наприклад, у виразі x + y + z компілятор обчислює значення x, потім значення y, складає ці два значення, обчислює значення z і додає його до попереднього результату Компілятор не стане обчислювати значення y перед x або z – перед y або x

Такий порядок має значення, якщо обчислення x, y і z має деякий побічний ефект Скажімо, якщо при цьому будуть викликатися методи, які змінюють стан обєкта або виводять небудь на друк, то зміна порядку обчислень відібється на роботі програми Мова гарантує, що цього не станеться

Всі операнди всіх операторів, за винятком &&, | | і: (Див нижче), обчислюються перед виконанням оператора Це твердження виявляється істинним навіть для тих операцій, в ході яких можуть виникнути винятки Наприклад, цілочисельне ділення на нуль призводить до запуску винятку ArithmeticException, але відбувається це лише після обчислення обох операндів

512 Тип виразу

У кожного виразу є певний тип Він задається типом компонентів вираження і семантикою операторів Якщо арифметичний або порозрядну оператор застосовується до вираження цілого типу, то результат буде мати тип int, якщо тільки у вираженні не бере значення типу long – в цьому випадку вираз також матиме тип long Всі цілочисельні операції виконуються з точністю int або long, так що менші цілі типи short і byte завжди перетворюються в int перед виконанням обчислень

Якщо хоча б один з операндів арифметичного оператора відноситься до типу з плаваючою точкою, то при виконанні оператора використовується речова арифметика Обчислення виконуються з точністю float, якщо тільки принаймні один з операндів не відноситься до типу double в цьому випадку обчислення проводяться з точністю double, і результат також має тип double

Оператор + виконує конкатенацію для типу String, якщо хоча б один з його операндів відноситься до типу String або ж змінна типу String стоїть в лівій частині оператора + =

При використанні у виразі значення char перетвориться в int по-засобом обнулення старших 16 біт Наприклад, символ Unicode \ uffff є еквівалентом цілого значення 0x0000ffff Трохи інакше розглядається значення типу short, рівне

0xffff, – з урахуванням знака воно дорівнює -1, тому його еквівалент в типі int буде дорівнює

0xffffffff

Джерело: Арнольд К, Гослінг Д – Мова програмування Java (1997)

Схожі статті:


Сподобалася стаття? Ви можете залишити відгук або підписатися на RSS , щоб автоматично отримувати інформацію про нові статтях.

Коментарів поки що немає.

Ваш отзыв

Поділ на параграфи відбувається автоматично, адреса електронної пошти ніколи не буде опублікований, допустимий HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

*

*