Во-первых, немного предыстории: я учитель-информатик, и я пытаюсь представить булевы операторы Java в своем классе 10-го класса. Мой учитель-наставник просмотрел рабочий лист, который я подготовил, и прокомментировал, что я могу позволить им использовать только один & или | обозначать операторов, потому что они «делают то же самое».
Я осознаю разницу между & и &&.
& является побитовым оператором, предназначенным для использования между целыми числами, для выполнения "сдвоенного бита".
&& - это условный оператор, предназначенный для использования между логическими значениями.
Чтобы доказать, что эти операторы не всегда «делают одно и то же», я решил найти пример, где использование побитового значения между логическими значениями приведет к ошибке. Я нашел этот пример
boolean bitwise;
boolean conditional;
int i=10, j=12;
bitwise = (i<j) | ((i=3) > 5); // value of i after oper: 3
System.out.println(bitwise+ " "+ i);
i=10;
conditional = (i<j) || (i=3) > 5 ; // value of i after oper: 10
System.out.println(conditional+ " "+ i);
i=10;
bitwise = (i>j) & (i=3) > 5; // value of i after oper: 3
System.out.println(bitwise+ " "+ i);
i=10;
conditional = (i>j) && (i=3) > 5; // value of i after oper: 10
System.out.println(conditional+ " "+ i);
Этот пример показывает, что, если значение должно быть изменено второй половиной выражения, это приведет к разнице между результатами, поскольку побитовый оператор является нетерпеливым, а условное поведение ведет себя как короткое замыкание (не оценивает вторую половина, если первая половина ложна в случае && и истина в случае ||).
У меня есть проблема с этим примером. Почему вы хотите изменить значение в то же время, когда вы сравниваете его? Это не похоже на надежный способ кодирования. Я всегда был против выполнения нескольких операций в одной строке моего производственного кода. Похоже, что «ковбой-программист», не имеющий совести в отношении возможности сопровождения своего кода, подойдет. Я знаю, что в некоторых областях код должен быть максимально компактным, но, конечно, это плохая практика в целом?
Я могу объяснить свой выбор поощрения использования && и || над & и | потому что это общепринятая кодировка в программной инженерии .
Но может ли кто-нибудь дать мне лучший, даже реальный, пример использования побитового оператора в условном выражении?
источник
bitwise = !(true & true == false);
иcondition = !(true && true == false);
будет как оценить, правда, так что в этом случае они взаимозаменяемы? Возможно, синтаксически, поскольку код все еще компилируется. Я бы согласился, что они используются для разных вещей семантически, как я упоминал в параграфе 2. Вы говорите это! и & "почти никогда не появляются в условных выражениях". Я ищу эти «почти никогда» дела и задаюсь вопросом, существуют ли они на законных основаниях.Небитовые операторы
&&
и||
являются операторами короткого замыкания. Другими словами,&&
если LHS ложно, RHS никогда не будет оцениваться; с,||
если LHS истинно, тогда RHS никогда не будет оцениваться. С другой стороны, побитовые операторы&
и не|
являются короткозамкнутыми, и всегда будут оценивать как LHS, так и RHS. В противном случае они эквивалентны вif
утверждении.Единственный раз, когда я вижу ценность в использовании операторов без короткого замыкания, это если RHS имеет какой-то желательный побочный эффект, который вы хотите, чтобы он происходил во всех случаях. Я не могу вспомнить конкретный пример, где вы хотели бы этого, и я не верю, что это хорошая практика, но это разница.
источник
Общий философский ответ заключается в том, что использование побитовых операторов для логических операторов нетипично и затрудняет чтение кода. На практике (для кода, который находится в производстве), более читаемый код легче поддерживать и, следовательно, более желателен.
Для реального использования потребности в операторах короткого замыкания, смотрите случаи, такие как:
Эти типы операций часто появляются в реальном коде.
источник
&
«труднее читать», чем 2? У меня нет примера, в котором 2 оператора не работают одинаково для булевых операндов. Я согласен с вашей точкой зрения по поводу более удобочитаемого и простого в обслуживании кода. Я хочу призвать их написать красивый код. Но иметь какое-то доказательство в сумке с инструментами было бы более убедительно, чем «потому что я так сказал». У меня есть ссылка на стандарт по этой ссылке, и, возможно, мне придется полагаться только на нее, если я не получу нужный мне пример. Как я спросил @Steve Haigh: должен ли Java указывать на это как ненадлежащее использование?Вы будете использовать побитовые операторы, если сравниваете перечисления битовой маски. Например, у вас есть перечисление состояний и объект, который может находиться в нескольких состояниях. В этом случае вы будете делать побитовые или назначать более одного состояния для вашего объекта.
например,
state = CONNECTED | IN_PROGRESS
гдеCONNECTED could be 0x00000001
иIN_PROGRESS 0x00000010
Для получения дополнительной информации посмотрите документацию перечисления флагов.
источник
более простой пример неправильности:
здесь у вас есть два условия, оба ненулевые; но побитовое
&
приводит к нулю.источник
(condA && condB)
ошибки, потому что && не работает в течение 2int
с, только 2 логических значений.(condA & condB)
в то время как правильно, вычисляет доint
и в Java, мы не можем сказать,if(int)
что это тоже ошибки. Ты первый, кто понял, что я ищу, - именно этот пример неправильности .(Boolean(condA) && Boolean(condB))
(думаюBoolean(x)
,true
для ненулевых целых чисел, верно?)((condA!=0) && (condB!=0))
?if (((condA!=0) && (condB!=0))) { System.out.println("correct"); } if (((condA!=0) & (condB!=0))) { System.out.println("never executed?"); }
выполняет оба оператора печати.