Мне просто интересно, почему мы обычно используем логическое ИЛИ ||
между двумя логическими значениями, а не поразрядным ИЛИ |
, хотя они оба работают хорошо.
Я имею в виду, посмотрите на следующее:
if(true | true) // pass
if(true | false) // pass
if(false | true) // pass
if(false | false) // no pass
if(true || true) // pass
if(true || false) // pass
if(false || true) // pass
if(false || false) // no pass
Можем ли мы использовать |
вместо ||
? То же самое с &
и &&
.
java
bitwise-operators
Eng.Fouad
источник
источник
||
и&&
короткое замыкание в то время как|
и&
хотят.&&
и||
, но никогда&
|
. Если вы делаете что-то, что зависит от побочных эффектов, я не понимаю, почему вы используете что-то подобное,(a & b | c)
потому что кто-то может легко подумать: «Я могу оптимизировать это, используя короткие версии».Ответы:
Если вы используете
||
и&&
форму, а не|
и&
форму этих операторов, Java не будет беспокоить , чтобы оценить правый операнд в одиночку.Это вопрос, хотите ли вы замкнуть оценку или нет - большую часть времени вы хотите.
Хороший способ проиллюстрировать преимущества короткого замыкания - рассмотреть следующий пример.
Еще одно преимущество, как отмечали Джереми и Питер, для короткого замыкания - это проверка нулевой ссылки:
больше информации
источник
foo != null && foo.hasBar()
foo != null && foo.hasBar()
) или быстрее (b || foo.timeConsumingCall()
). 99% разработчиков не должны беспокоиться об этом уровне микрооптимизации.string == null || string.isEmpty()
;)|
не выполняет оценку короткого замыкания в логических выражениях.||
прекратит оценку, если первый операнд верен, но|
не будет.Кроме того,
|
может использоваться для выполнения операции побитового ИЛИ для байтовых / коротких / целых / длинных значений.||
не может.источник
Так что просто для того, чтобы использовать другие ответы на примере, короткое замыкание имеет решающее значение в следующих защитных проверках:
Использование
|
и&
вместо этого может привести к тому,NullPointerException
что вас бросят сюда.источник
foo
. «Канонический пример» Питера Лоури - лучший.Логично
||
и&&
проверяйте правую сторону только при необходимости.|
И&
проверить обе стороны каждый раз .Например:
Перепишите это:
Другой пример:
Перепишите это:
источник
Также обратите внимание на типичную ловушку: операторы без ленивства имеют приоритет над ленивыми, поэтому:
Будьте осторожны при их смешивании.
источник
В дополнение к короткому замыканию, следует помнить, что выполнение побитовой логической операции со значениями, которые могут быть отличны от 0 или 1, имеет совершенно иной смысл, чем условная логика. Хотя он ОБЫЧНО одинаков для
|
и||
, с&
и&&
вы получите очень разные результаты (например2 & 4
, 0 / false, а2 && 4
1 / true).Если то, что вы получаете от функции, на самом деле является кодом ошибки, и вы проверяете не ноль, это может иметь большое значение.
Это не такая большая проблема в Java, где вам приходится явно приводить тип к булевому или сравнивать с 0 и т.п., но в других языках с похожим синтаксисом (C / C ++ и др.) Это может быть довольно запутанным.
Также обратите внимание, что & и | может применяться только к значениям целочисленного типа, а не ко всему, что может быть эквивалентно булевому тесту. Опять же, в не-Java языках существует довольно много вещей, которые можно использовать в качестве логического значения с неявным
!= 0
сравнением (указатели, числа с плавающей точкой, объекты с иoperator bool()
т. Д.), И побитовые операторы почти всегда бессмысленны в этих контекстах.источник
Единственный раз, когда вы будете использовать
|
или&
вместо,||
или&&
когда у вас будут очень простые логические выражения и стоимость сокращения (т. Е. Ветви) будет больше, чем время, которое вы сэкономите, не оценив последующие выражения.Тем не менее, это микрооптимизация, которая редко имеет значение, за исключением кода самого низкого уровня.
источник
|| является логическим или оператором в то время как | является побитовым или оператором.
источник
а | б: оценить б в любом случае
|| b: оценивать b, только если a оценивается как ложное
источник
Помимо того, что | является побитовым оператором: || является оператором короткого замыкания - когда один элемент ложен, он не будет проверять другие.
если что-то ИСТИННО, || не буду ничего оценивать, пока | Сделаю. Если переменные в ваших операторах if на самом деле являются вызовами функций, используйте || возможно, сохранит много производительности.
источник
источник
Операторы
||
и&&
называются условными операторами , а|
и&
называются побитовыми операторами . Они служат разным целям.Условные операторы работают только с выражениями, которые статически вычисляются
boolean
как слева, так и справа.Побитовые операторы работают с любыми числовыми операндами.
Если вы хотите выполнить логическое сравнение, вы должны использовать условные операторы , так как вы добавите некоторый тип безопасности типов в свой код.
источник
|
и&
тоже условные операторы. Пожалуйста, смотрите ссылку в моем комментарии к оригинальному сообщению.|
и&
могут быть использованы как побитовые операторы, является совершенно отдельной проблемой.Примечание: у Java есть | =, но нет || =
Пример того, когда вы должны использовать || это когда первое выражение является тестом, чтобы увидеть, взорвется ли второе выражение. Например, используя один | в следующем случае может привести к NPE.
источник
Другие ответы хорошо справились с функциональной разницей между операторами, но ответы могут относиться практически ко всем существующим на сегодняшний день C-производным языкам. Вопрос отмеченЯваи поэтому я постараюсь ответить конкретно и технически за язык Java.
&
и|
может быть либо целочисленным побитовым оператором, либо логическим логическим оператором. Синтаксис для побитовых и логических операторов ( §15.22 ):Синтаксис
EqualityExpression
определен в §15.21 , что требуетRelationalExpression
определенных в §15.20 , который , в свою очередь , требуетShiftExpression
иReferenceType
определено в §15.19 и §4.3 , соответственно.ShiftExpression
требуетAdditiveExpression
определения, определенного в §15.18 , который продолжает детализацию, определяя основные арифметические, унарные операторы и т. д.,ReferenceType
детализирует все различные способы представления типа. ( В то время какReferenceType
не включает в себя примитивные типы, определение примитивных типов, в конечном счете требуется, так как они могут быть типом измерения для массива, который являетсяReferenceType
.)Битовые и логические операторы имеют следующие свойства:
Различие между тем, служит ли оператор как побитовый оператор или логическим оператором, зависит от того, являются ли операнды «конвертируемыми в примитивный целочисленный тип» ( §4.2 ) или они имеют типы
boolean
илиBoolean
( §5.1.8 ).Если операнды являются целочисленными типами, двоичное числовое продвижение ( §5.6.2 ) выполняется для обоих операндов, оставляя их как
long
s илиint
s для операции. Тип операции будет типом (повышенных) операндов. В этот момент&
будет побитовое И,^
будет побитовое исключающее ИЛИ и|
будет побитовое ИЛИ. ( §15.22.1 )Если операндами являются
boolean
илиBoolean
, операнды при необходимости будут преобразованы в распаковку ( §5.1.8 ), и тип операции будетboolean
.&
приведет к тому,true
что оба операнда равныtrue
,^
приведет к тому,true
что оба операнда различны, и|
к тому,true
если один из операндов будетtrue
. ( §15.22.2 )Напротив,
&&
это «Условный оператор И» ( §15.23 ) и||
«Оператор Условного И » ( §15.24 ). Их синтаксис определяется как:&&
похоже&
, за исключением того, что он оценивает правый операнд, только если левый операндtrue
.||
похоже|
, за исключением того, что он оценивает правый операнд, только если левый операндfalse
.Условно-А обладает следующими свойствами:
Условно-Или имеет следующие свойства:
Короче, как @JohnMeagher неоднократно указывал в комментариях,
&
и|
, по сути, не замыкая логические операторы в конкретном случае операндов , являющихся либоboolean
илиBoolean
. С хорошими практиками (то есть: никакие вторичные эффекты), это незначительная разница. Однако, когда операнды неboolean
s илиBoolean
s, операторы ведут себя очень по- разному: побитовые и логические операции просто не сравниваются на высоком уровне программирования Java.источник
1). (Выражение1 | выражение2), | Оператор будет оценивать expression2 независимо от того, является ли результат expression1 истинным или ложным.
Пример:
2). (Выражение1 || выражение2), || Оператор не будет оценивать expression2, если expression1 истинно.
Пример:
источник
|| возвращает логическое значение, используя два значения ИЛИ (поэтому его называют ЛОГИЧЕСКИМ или)
IE:
Вернет true, если A или B - true, или false, если они оба false.
| является оператором, который выполняет побитовую операцию над двумя значениями. Чтобы лучше понять побитовые операции, вы можете прочитать здесь:
http://en.wikipedia.org/wiki/Bitwise_operation
источник
Одно главное отличие заключается в том, что || и && демонстрируют «короткое замыкание», поэтому RHS будет оцениваться только при необходимости.
Например,
Выше, если a равно true, b не будет проверяться, и path1 выполняется. Если | Тогда обе стороны будут оценены, даже если «а» истинно.
Смотрите здесь и здесь , для получения дополнительной информации.
Надеюсь это поможет.
источник
Не короткое замыкание может быть полезным. Иногда вы хотите убедиться, что два выражения оценивают. Например, скажем, у вас есть метод, который удаляет объект из двух отдельных списков. Возможно, вы захотите сделать что-то вроде этого:
Если ваш метод вместо этого использовал условный операнд, он не сможет удалить объект из второго списка, если первый список вернул false.
Это не удивительно полезно, и (как и в большинстве задач программирования) вы можете достичь этого другими способами. Но это случай использования побитовых операндов.
источник
Основное различие между ними заключается в том, что | сначала преобразует значения в двоичные, затем выполняет битовую обработку или операцию. Между тем, || не преобразует данные в двоичный файл, а просто выполняет выражение или в исходном состоянии.
Читать подробнее: http://javarevisited.blogspot.com/2015/01/difference-between-bitwsie-and-logical.html#ixzz45PCxdQhk
источник
Когда у меня возник этот вопрос, я создал тестовый код, чтобы получить представление об этом.
В этом случае мы меняем только левое значение условия if, добавляя a или b.
вывод
"If condition executed"
Вывод-
Conclusion of ||
При использовании||
правая сторона проверяет только когда левая сторона ложна.Вывод-
Вывод-
Conclusion of |
При использовании|
проверяйте как левую, так и правую сторону.источник
| = побитовый или, || = логика или
источник
обычно я использую, когда есть прединкрементный и постинкрементный оператор. Посмотрите на следующий код:
вывод:
оба
if
блока одинаковы, но результат различен. когда есть|
, оба условия будут оценены. Но если это так||
, он не будет оценивать второе условие, поскольку первое условие уже выполнено.источник
Есть много вариантов использования, предлагающих, почему вы должны пойти,
||
а не|
. В некоторых случаях необходимо использовать|
оператор для проверки всех условий.Например, если вы хотите проверить проверку формы и хотите показать пользователю все недопустимые поля с текстами ошибок, а не только первое недопустимое поле.
||
оператор будет,Таким образом, с приведенным выше фрагментом, если пользователь отправляет форму со ВСЕМИ пустыми полями, ТОЛЬКО
nameField
будет показано сообщение об ошибке. Но если вы измените его наОн покажет правильное сообщение об ошибке в каждом поле, независимо от
true
условий.источник
После внимательного прочтения этой темы мне все еще непонятно, используете ли
|
в качестве логического оператора практикам шаблонов Java.Я недавно изменил код в запросе на удаление, обращаясь к комментарию, где
должен был быть изменен на
Какова фактически принятая версия?
Не заинтересован в голосовании, но больше в поиске стандарта ?! Обе версии кода компилируются и работают как положено.
источник
|| логично или и | является немного мудрым или.
источник
Операторы Java
| побитовый или, || логично или.
источник
Взгляни на:
http://java.sun.com/docs/books/tutorial/java/nutsandbolts/operators.html
| поразрядно включительно ИЛИ
|| логично ИЛИ
источник
| является побитовым оператором. || логический оператор
Один займет два бита и / или их.
Кто-то определит истину (это ИЛИ это). Если это правда или это правда, тогда ответ верен.
Ох, и черт побери, люди быстро отвечают на эти вопросы.
источник