Кен Арнольд Джеймс Гослинг
Вид материала | Документы |
Содержание5.10. Приоритет и ассоциативность операторов 5.11. Порядок вычислений |
- Джеймс трефил, 41001.36kb.
- Джеймс А. Дискретная математика и комбинаторика [Текст] / Джеймс А. Андерсон, 42.79kb.
- Человеческая способность эти ценности производить и использовать; является важнейшей, 110.76kb.
- Джеймс блиш города в полете 1-4 триумф времени вернись домой, землянин жизнь ради звезд, 10495.38kb.
- Джеймс Н. Фрей. Как написать гениальный роман, 2872.12kb.
- Дп «авто интернешнл» Київ, вул. Урицького, 1а Тел. (044) 20-60-333 Факс. (044) 20-60-343, 82.44kb.
- Тема Кол-во страниц, 26.85kb.
- Тема Кол-во страниц, 56.3kb.
- Тема Кол-во страниц, 20.7kb.
- Арнольд И. В. Стилистика современного английского языка, 20.42kb.
5.10. Приоритет и ассоциативность операторов
Приоритетом (precedence) оператора называется порядок, в котором он выполняется по отношению к другим операторам. Различные операторы имеют различные приоритеты. Например, приоритет условных операторов выше, чем у логических, поэтому вы можете написать
if (i >>= min && i <<= 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 = stream.next()) != null)
processValue(v);
Приоритет операторов присваивания ниже, чем у операторов равенства; без скобок наш пример был бы равносилен следующему:
while (v = (stream.next() != null)) // НЕВЕРНО
processValue(v);
что, вероятно, отличается от ожидаемого порядка вычислений. Кроме того, конструкция без скобок, скорее всего, окажется неверной — она будет работать лишь в маловероятном случае, если v имеет тип boolean.
Приоритет поразрядных логических операторов &, и | также может вызвать некоторые затруднения. Бинарные поразрядные операторы в сложных выражениях тоже следует заключать в скобки, чтобы облегчить чтение выражения и обеспечить правильность вычислений.
В этой книге скобки употребляются довольно редко — лишь в тех случаях, когда без них смысл выражения будет неочевидным. Приоритеты операторов являются важной частью языка и их нужно знать. Многие программисты склонны злоупотреблять скобками. Старайтесь не пользоваться скобками там, где без них можно обойтись — перегруженная скобками программа становится неудобочитаемой и начинает напоминать LISP, не приобретая, однако, ни одного из достоинств этого языка.
5.11. Порядок вычислений
Язык Java гарантирует, что операнды в операторах вычисляются слева направо. Например, в выражении x+y+z компилятор вычисляет значение x, потом значение y, складывает эти два значения, вычисляет значение z и прибавляет его к предыдущему результату. Компилятор не станет вычислять значение y перед x или z — перед y или x.
Такой порядок имеет значение, если вычисление x, y и z имеет некоторый побочный эффект. Скажем, если при этом будут вызываться методы, которые изменяют состояние объекта или выводят что-нибудь на печать, то изменение порядка вычислений отразится на работе программы. Язык гарантирует, что этого не произойдет.
Все операнды всех операторов, за исключением &&, || и ?: (см. ниже), вычисляются перед выполнением оператора. Это утверждение оказывается истинным даже для тех операций, в ходе которых могут возникнуть исключения. Например, целочисленное деление на ноль приводит к запуску исключения ArithmeticException, но происходит это лишь после вычисления обоих операндов.