Respostas:
Esses são os operadores bit a bit AND e bit a bit OR.
int a = 6; // 110
int b = 4; // 100
// Bitwise AND
int c = a & b;
// 110
// & 100
// -----
// 100
// Bitwise OR
int d = a | b;
// 110
// | 100
// -----
// 110
System.out.println(c); // 4
System.out.println(d); // 6
Obrigado a Carlos por apontar a seção apropriada nas especificações da linguagem Java ( 15.22.1 , 15.22.2 ) sobre os diferentes comportamentos do operador com base em suas entradas.
De fato, quando ambas as entradas são booleanas, os operadores são considerados Operadores Lógicos Booleanos e se comportam de maneira semelhante aos operadores Conditional-And ( &&
) e Conditional-Or ( ||
), exceto pelo fato de que eles não entram em curto-circuito, portanto, o seguinte é seguro :
if((a != null) && (a.something == 3)){
}
Isso não é:
if((a != null) & (a.something == 3)){
}
"Curto-circuito" significa que o operador não examina necessariamente todas as condições. Nos exemplos acima, &&
examinará a segunda condição somente quando a
não for null
(caso contrário, toda a declaração retornará falsa, e seria discutível examinar as seguintes condições de qualquer maneira), então a declaração de a.something
não levantará uma exceção ou é considerada "segura . "
O &
operador sempre examina todas as condições da cláusula, portanto, nos exemplos acima, a.something
pode ser avaliada quando a
é de fato um null
valor, gerando uma exceção.
Acho que você está falando sobre o significado lógico de ambos os operadores, aqui você tem um resumo da tabela:
boolean a, b;
Operation Meaning Note
--------- ------- ----
a && b logical AND short-circuiting
a || b logical OR short-circuiting
a & b boolean logical AND not short-circuiting
a | b boolean logical OR not short-circuiting
a ^ b boolean logical exclusive OR
!a logical NOT
short-circuiting (x != 0) && (1/x > 1) SAFE
not short-circuiting (x != 0) & (1/x > 1) NOT SAFE
Avaliação de curto-circuito , avaliação mínima ou avaliação de McCarthy (após John McCarthy) é a semântica de alguns operadores booleanos em algumas linguagens de programação em que o segundo argumento é executado ou avaliado apenas se o primeiro argumento não for suficiente para determinar o valor do expressão: quando o primeiro argumento da função AND é avaliado como falso, o valor geral deve ser falso; e quando o primeiro argumento da função OR for avaliado como verdadeiro, o valor geral deve ser verdadeiro.
Não seguro significa que o operador sempre examina todas as condições na cláusula, portanto, nos exemplos acima, 1 / x pode ser avaliado quando x é, de fato, um valor 0, gerando uma exceção.
Sei que há muitas respostas aqui, mas todas parecem um pouco confusas. Então, depois de fazer algumas pesquisas no guia de estudo do oráculo Java, eu vim com três cenários diferentes de quando usar && ou &. Os três cenários são AND lógico , AND bit a bit e AND booleano .
E lógico: E
lógico (também conhecido como E condicional) usa o operador && . É o significado de curto-circuito: se o operando esquerdo for falso, o operando direito não será avaliado.
Exemplo:
int x = 0;
if (false && (1 == ++x) {
System.out.println("Inside of if");
}
System.out.println(x); // "0"
No exemplo acima, o valor impresso no console de x será 0, porque o primeiro operando na instrução if é falso, portanto, java não precisa calcular (1 == ++ x), portanto, x não será calculado.
AND bit a bit: AND bit a bit usa o operador & . É usado para executar uma operação bit a bit no valor. É muito mais fácil ver o que está acontecendo observando a operação em números binários, por exemplo:
int a = 5; // 5 in binary is 0101
int b = 12; // 12 in binary is 1100
int c = a & b; // bitwise & preformed on a and b is 0100 which is 4
Como você pode ver no exemplo, quando as representações binárias dos números 5 e 12 estão alinhadas, um AND bit a bit pré-formado produzirá apenas um número binário onde o mesmo dígito em ambos os números tem um 1. Portanto, 0101 & 1100 == 0100. Que em decimal é 5 e 12 == 4.
AND booleano: agora, o operador AND booleano se comporta de maneira semelhante e diferente tanto para o AND bit a bit quanto para o AND lógico. Eu gosto de pensar nisso como a execução de um AND bit a bit entre dois valores booleanos (ou bits), portanto, ele usa o operador & . Os valores booleanos também podem ser o resultado de uma expressão lógica.
Ele retorna um valor verdadeiro ou falso, muito parecido com o AND lógico, mas ao contrário do AND lógico, não é curto-circuitado. A razão é que, para executar aquele AND bit a bit, ele deve saber o valor dos operandos esquerdo e direito. Aqui está um ex:
int x = 0;
if (false & (1 == ++x) {
System.out.println("Inside of if");
}
System.out.println(x); //"1"
Agora, quando essa instrução if for executada, a expressão (1 == ++ x) será executada, mesmo que o operando esquerdo seja falso. Portanto, o valor impresso para x será 1 porque foi incrementado.
Isso também se aplica a OR lógico (||), OR bit a bit (|) e OR booleano (|) Espero que isso esclareça alguma confusão.
to preform that bitwise AND, it must know the value of both left and right operands
Isso não parece certo para mim. Para executar um, BITWISE AND
você não precisa saber o operando direito para poder descobrir o resultado se o operando esquerdo for FALSE
. O que você explica está correto, mas o raciocínio que você afirma não parece ser, pelo menos para mim ..
Os operadores && e || estão em curto-circuito, o que significa que não avaliarão a expressão da mão direita se o valor da expressão da mão esquerda for suficiente para determinar o resultado.
& e | fornecem o mesmo resultado que && e || operadores. A diferença é que eles sempre avaliam ambos os lados da expressão onde como && e || pare de avaliar se a primeira condição é suficiente para determinar o resultado.
&&
ele avalia os dois resultados, enquanto ||
retorna apenas se a primeira condição for verdadeira.
( 2 & 4 )
avalia para false
, enquanto ( 2 && 4 )
avalia para true
. Como exatamente esse é o mesmo resultado?
2 & 4
resulta em um inteiro, não um booleano (zero neste caso). 2 && 4
não irá compilar, && apenas aceita booleanos. Java não permite misturar booleanos e ints: zero não é false
, false
não é zero ...
&&
ele só avalia o segundo operando se o primeiro operando for true
.
Em Java, os operadores únicos &, |, ^,! dependem dos operandos. Se ambos os operandos forem ints, uma operação bit a bit será executada. Se ambos forem booleanos, uma operação "lógica" será executada.
Se ambos os operandos forem incompatíveis, um erro de tempo de compilação será gerado.
Os operadores duplos &&, || se comportam de maneira semelhante a suas contrapartes únicas, mas ambos os operandos devem ser expressões condicionais, por exemplo:
if ((a <0) && (b <0)) {...} ou similarmente, if ((a <0) || (b <0)) {...}
fonte: linguagem de programação java 4ª ed
&
e |
são operadores bit a bit em tipos integrais (por exemplo int
): http://download.oracle.com/javase/tutorial/java/nutsandbolts/op3.html
&&
e ||
operar apenas em booleanos (e curto-circuito, como outras respostas já disseram).
&
e |
também são operadores booleanos em tipos booleanos.
Talvez seja útil saber que os operadores AND bit a bit e OR bit a bit são sempre avaliados antes do AND condicional e do OR condicional usados na mesma expressão.
if ( (1>2) && (2>1) | true) // false!
&&; || são operadores lógicos ... curto-circuito
&; | são operadores lógicos booleanos ... Não curto-circuito
Movendo para diferenças na execução de expressões. Operadores bit a bit avaliam ambos os lados independentemente do resultado do lado esquerdo. Mas, no caso de avaliar expressões com operadores lógicos, a avaliação da expressão do lado direito depende da condição do lado esquerdo.
Por exemplo:
int i = 25;
int j = 25;
if(i++ < 0 && j++ > 0)
System.out.println("OK");
System.out.printf("i = %d ; j = %d",i,j);
Isso imprimirá i = 26; j = 25, Como a primeira condição é falsa, a condição do lado direito é ignorada, pois o resultado é falso de qualquer maneira, independentemente da condição do lado direito. (curto-circuito)
int i = 25;
int j = 25;
if(i++ < 0 & j++ > 0)
System.out.println("OK");
System.out.printf("i = %d ; j = %d",i,j);
Mas, isso imprimirá i = 26; j = 26,
Se uma expressão envolvendo o operador booleano & for avaliada, ambos os operandos serão avaliados. Em seguida, o operador & é aplicado ao operando.
Quando uma expressão envolvendo o operador && é avaliada, o primeiro operando é avaliado. Se o primeiro operando for avaliado como falso, a avaliação do segundo operando será ignorada.
Se o primeiro operando retornar um valor verdadeiro, o segundo operando será avaliado. Se o segundo operando retornar um valor verdadeiro, o operador && é então aplicado ao primeiro e ao segundo operandos.
Semelhante para | e ||.
Embora a diferença básica seja que &
é usado principalmente para operações bit a bit long
, int
ou byte
onde pode ser usado para uma espécie de máscara, os resultados podem ser diferentes, mesmo se você usá-lo em vez de lógico &&
.
A diferença é mais perceptível em alguns cenários:
O primeiro ponto é bastante direto, não causa bugs, mas leva mais tempo. Se você tiver várias verificações diferentes em uma instrução condicional, coloque à esquerda aquelas que são mais baratas ou com maior probabilidade de falhar.
Para o segundo ponto, veja este exemplo:
if ((a != null) & (a.isEmpty()))
Isso falha null
, pois a avaliação da segunda expressão produz a NullPointerException
. O operador lógico &&
é preguiçoso; se o operando esquerdo for falso, o resultado será falso, independentemente do operando direito.
Exemplo para o terceiro ponto - digamos que temos um aplicativo que usa DB sem gatilhos ou cascatas. Antes de remover um objeto Edifício, devemos mudar o edifício de um objeto Departamento para outro. Digamos também que o status da operação seja retornado como um booleano (verdadeiro = sucesso). Então:
if (departmentDao.update(department, newBuilding) & buildingDao.remove(building))
Isso avalia ambas as expressões e, portanto, executa a remoção do edifício, mesmo se a atualização do departamento falhou por algum motivo. Com &&
, ele funciona como pretendido e para após a primeira falha.
Quanto a a || b
, é equivalente a !(!a && !b)
, pára se a
for verdade, nenhuma explicação mais necessária.