![]() |
Java для программистов и разработчиков Архив от 22-08-2008 |
![]() | |
Выпуск 10 - Укороченные (short-circuit) логические операторы && и ||Укороченные (short-circuit) логические операторы && и || предназначаются для логических AND (И) и OR (ИЛИ) операций над выражениями типа boolean. Заметьте, что для XOR (исключающее ИЛИ) операции не существует укороченного логического оператора. Укороченные логические операторы похожи на операторы & и |, но в отличие от них применяются только к выражениям типа boolean и никогда не применяются к интегральным типам. Тем не менее, && и || обладают замечательным свойством: они укорачивают вычисление выражения, если результат может быть дедуцирован из части выражения (чуть позже я поясню это на примерах). Благодаря этому свойству, операторы && и || широко используются для обработки null-выражений. Они также помогают увеличить эффективность всей программы. Свойство укорачивания вытекает прямым образом из различий между &&/|| и &/|: последняя пара операторов должна получать на вход значения левого и правого операторов, в то время как для первой пары операторов иногда достаточно знать значение только левого операнда, чтобы вернуть значение всего выражения. Такое поведение укороченных логических операторов базируется на двух математических правилах логической таблицы истинности:
Иными словами:
То есть, если левый операнд AND выражения ложен, то и всё выражение ложно, вне зависимости от значения правого операнда. То есть при ложном левом операнде нет нужны вычислять значение правого операнда. Аналогичным образом, если левый операнд OR выражения истиннен, то истинно и всё выражения, вне зависимости от значения правого операнда, которое, следовательно, нам не нужно вычислять. Рассмотрим пример кода, который выводит сообщение String, если строка не нулевая и более 20 символов длиной:
Эта же задача может быть закодиравана по-другому:
Если бы строка s была null, то при вызове метода s.length() мы бы получили NullPointerException. Ни в одном из двух примеров кода, однако, такая ситауция не возникнет. В частности, во втором примере, s.length() не вызывается при s = null, благодаря использованию укороченного оператора &&. Если бы тест (s!=null) возвращал ложь (false), то есть s - несуществующая строка, то и всё выражение гарантированно ложно. Значит, отпадает необхеодимость вычислять значение второго операнда, то есть выражения (s.length()>20). Однако данные операторы имеют побочные эффекты. Например, если правый операнд является выражением, выполняющим некую операцию, то при применении укороченных операторов, эта операция может оазаться невыполненной в случае ложного левого операнда. Рассмотрим пример:
Первый пример иногда будет выводить на печать вот это:
А иногда вот это:
Второй пример иногда будет выводить на печать вот это:
А иногда вот это:
А дело вот в чём. Если val равно 0, то второй операнд (++val) никогда не будет вычислен, то есть val останется равным нулю. Если же изначально val равен единице, то в результате эта переменная будет инкрементирована и мы увидим val = 2. Во втором примере, при использовании неукороченных операторов, инкремент выполняется всегда и результат будет всегда или 1 или 2 в зависимости от случайного значения выбранного на первом шаге. В обоих примерах переменная test принимает значение true, потому что либо val = 0, либо val = 1 и инкрементируется до значения 2. Резюмируем информацию об укороченных операторах && и ||:
Мои рассылкиДорогие читатели! Если у вас возникают вопросы по тексту рассылки, я с удовольствием на них отвечу. Мой почтовый адрес идёт последней строкой в данном выпуске (at означает @). Кроме того, присылайте мне интересующие вас темы, которые я могла бы осветить в рассылке, делитесь опытом или просто комментируйте. Всего доброго, Внимание! По вопросам партнёрства обращаться на е-майл natalia.macheda at gmail.com © Наталия Македа 2008 |