Qual é a diferença entre & e && em Java?

168

Eu sempre pensei que o &&operador em Java é usado para verificar se ambos os operandos booleanos são truee o &operador é usado para fazer operações bit a bit em dois tipos inteiros.

Recentemente, soube que o &operador também pode ser usado para verificar se ambos os operandos booleanos são true, a única diferença é que ele verifica o operando RHS, mesmo que o operando LHS seja falso.

O &operador em Java está sobrecarregado internamente? Ou existe algum outro conceito por trás disso?

Comunidade
fonte
3
Possível duplicata de Por que geralmente usamos `||` not `|`, qual é a diferença?
Blake Yarbrough
Double executa atalho, se possível.
Nicholas Hamilton

Respostas:

278

& <- verifica os dois operandos
&& <- pára de avaliar se o primeiro operando é avaliado como falso, pois o resultado será falso

(x != 0) & (1/x > 1)<- isso significa avaliar (x != 0)e avaliar (1/x > 1)e executar o &. o problema é que, para x = 0, isso gera uma exceção.

(x != 0) && (1/x > 1)<- isso significa avaliar (x != 0)e somente se isso for verdade, avalie-o (1/x > 1), se você tiver x = 0, então é perfeitamente seguro e não lançará nenhuma exceção se (x! = 0) avaliar como falso, a coisa toda avaliar diretamente como falso sem avaliar o (1/x > 1).

EDITAR:

exprA | exprB<- isso significa avaliar exprAe avaliar e exprBdepois fazer o |.

exprA || exprB<- isso significa avaliar exprAe somente se for falseentão avaliar exprBe fazer o ||.

ITroubs
fonte
7
Qual é o motivo para escrever um & ou | na declaração if? Nunca será mais rápido que && e ||. Por que queremos verificar a segunda condição, se já podemos ter resposta? Você pode fornecer um exemplo realista, por favor?
Michu93
14
@ Michu93: Um exemplo seria se a segunda condição for uma chamada de função que tenha um efeito colateral que você sempre precisa. Como os efeitos colaterais geralmente devem ser evitados, haverá apenas casos raros em que você precisa disso, e não consigo pensar em um exemplo realista no momento.
Heinzi 14/08
54

Além de não ser um avaliador preguiçoso, avaliando os dois operandos, acho que as principais características dos operadores bit a bit comparam cada bytes de operandos como no exemplo a seguir:

int a = 4;
int b = 7;
System.out.println(a & b); // prints 4
//meaning in an 32 bit system
// 00000000 00000000 00000000 00000100
// 00000000 00000000 00000000 00000111
// ===================================
// 00000000 00000000 00000000 00000100
suat
fonte
2
A questão é sobre operações lógicas booleanas, não operações bit a bit.
Marquês de Lorne
21
@EJP Ajuda ainda os googlers como eu, que leem apenas o título.
Ad Infinitum
29
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
Torres
fonte
Obrigado Andreas para a edição, talvez esta outra questão também ajuda: stackoverflow.com/questions/4014535/vs-and-vs
Torres
11

Depende do tipo dos argumentos ...

Para argumentos inteiros, o único e comercial ("&") é o operador "bit a bit AND". O e comercial duplo ("&&") não está definido para nada além de dois argumentos booleanos.

Para argumentos booleanos, o e comercial único constitui o operador "AND lógico" (incondicional) enquanto o e comercial duplo ("&&") é o operador "AND lógico condicional". Ou seja, o único e comercial sempre avalia os dois argumentos, enquanto o duplo e comercial apenas avalia o segundo argumento se o primeiro argumento for verdadeiro.

Para todos os outros tipos e combinações de argumentos, um erro em tempo de compilação deve ocorrer.

desenvolvedor
fonte
9

&& é um operador de curto-circuito, enquanto & é um operador AND.

Tente isso.

    String s = null;
    boolean b = false & s.isEmpty(); // NullPointerException
    boolean sb = false && s.isEmpty(); // sb is false
Prince John Wesley
fonte
7

é como especificado no JLS (15.22.2) :

Quando os dois operandos de um &, ^ ou | Se o operador é do tipo booleano ou booleano, o tipo da expressão de operador bit a bit é booleano. Em todos os casos, os operandos estão sujeitos à conversão de unboxing (§5.1.8) conforme necessário.

Para &, o valor do resultado é verdadeiro se os dois valores do operando forem verdadeiros; caso contrário, o resultado é falso.

Para ^, o valor do resultado é verdadeiro se os valores do operando forem diferentes; caso contrário, o resultado é falso.

Para |, o valor do resultado será falso se os dois valores do operando forem falsos; caso contrário, o resultado é verdadeiro.

O "truque" é que &é um operador inteiro bit a bit e um operador lógico booleano . Então, por que não, considerar isso um exemplo de sobrecarga do operador ?

Andreas Dolk
fonte
7

Eu acho que minha resposta pode ser mais compreensível:

Existem duas diferenças entre &e &&.

Se eles usam como AND lógico

&e &&pode ser lógico AND, quando o &ou &&para a esquerda e resultar expressão certa tudo é verdadeiro, todo o resultado da operação pode ser verdade.

quando &e &&como lógico AND, há uma diferença:

quando usado &&como lógico AND, se o resultado da expressão esquerda for falso, a expressão correta não será executada.

Veja o exemplo:

String str = null;

if(str!=null && !str.equals("")){  // the right expression will not execute

}

Se estiver usando &:

String str = null;

if(str!=null & !str.equals("")){  // the right expression will execute, and throw the NullPointerException 

}

Outro outro exemplo:

int x = 0;
int y = 2;
if(x==0 & ++y>2){
    System.out.print(“y=”+y);  // print is: y=3
}

int x = 0;
int y = 2;
if(x==0 && ++y>2){
    System.out.print(“y=”+y);  // print is: y=2
}

& pode ser usado como operador de bit

&pode ser usado como ANDoperador Bitwise , &&não pode.

O operador AND "&" bit a bit produz 1 se e somente se os dois bits de seus operandos forem 1. No entanto, se os dois bits forem 0 ou os dois bits forem diferentes, esse operador produzirá 0. Para ser mais preciso, o bit a bit O operador AND "&" retorna 1 se qualquer um dos dois bits for 1 e retorna 0 se qualquer um dos bits for 0. 

Na página wiki:

http://www.roseindia.net/java/master-java/java-bitwise-and.shtml

aeronave
fonte
4

'&&': - é um operador Lógico AND que produz um valor booleano de true ou false com base no relacionamento lógico de seus argumentos.

Por exemplo: - Condição1 && Condição2

Se a Condição1 for falsa, (Condição1 e& Condição2) sempre será falsa, esse é o motivo pelo qual esse operador lógico também é conhecido como Operador de Curto-Circuito, porque não avalia outra condição. Se a Condição1 for falsa, não será necessário avaliar o Condtiton2.

Se a Condição1 for verdadeira, a Condição2 será avaliada; se for verdadeira, o resultado geral será verdadeiro; caso contrário, será falso.

'&': - é um operador AND bit a bit. Produz um (1) na saída se os dois bits de entrada forem um. Caso contrário, produz zero (0).

Por exemplo:-

int a = 12; // representação binária de 12 é 1100

int b = 6; // representação binária de 6 é 0110

int c = (a & b); // a representação binária de (12 e 6) é 0100

O valor de c é 4.

para referência, consulte este http://techno-terminal.blogspot.in/2015/11/difference-between-operator-and-operator.html

satish
fonte
3

&&e ||são chamados de operadores de curto-circuito. Quando eles são usados, para ||- se o primeiro operando for avaliado true, o restante dos operandos não será avaliado. Para &&- se o primeiro operando for avaliado false, o restante deles não será avaliado.

portanto if (a || (++x > 0)), neste exemplo, a variável x não será incrementada se a for true.

ACV
fonte
3

Com os booleanos, não há diferença de saída entre os dois. Você pode trocar && e & ou || e | e isso nunca mudará o resultado da sua expressão.

A diferença está nos bastidores em que as informações estão sendo processadas. Quando você corrige uma expressão "(a! = 0) & (b! = 0)" para a = 0 eb = 1, acontece o seguinte:

left side: a != 0 --> false
right side: b 1= 0 --> true
left side and right side are both true? --> false
expression returns false

Quando você escreve uma expressão (a != 0) && ( b != 0)quando a = 0 eb = 1, acontece o seguinte:

a != 0 -->false
expression returns false

Menos etapas, menos processamento, melhor codificação, especialmente ao fazer muitas expressões booleanas ou argumentos complicados.

Ryan
fonte
2
Isso mudará o resultado geral da expressão se os operandos tiverem efeitos colaterais.
Marquês de Lorne
3

Além de && e || sendo um curto-circuito, considere também a precedência do operador ao misturar as duas formas. Eu acho que não será imediatamente aparente para todos que result1 e result2 contêm valores diferentes.

boolean a = true;
boolean b = false;
boolean c = false;

boolean result1 = a || b && c; //is true;  evaluated as a || (b && c)
boolean result2 = a  | b && c; //is false; evaluated as (a | b) && c
mgr326639
fonte
0

& é um operador bit a bit mais usado para verificar as duas condições, porque às vezes precisamos avaliar as duas condições. Mas o operador lógico && passa para a 2ª condição quando a primeira condição é verdadeira.

Yasir Shabbir Choudhary
fonte
0

todas as respostas são great, e parece que há nomais respostas, is needed mas eu apenas queria apontar algo sobre o &&operador chamadodependent condition

Nas expressões que usam operador &&, uma condição - chamaremos isso de dependent condition- pode exigir que outra condição seja verdadeira para que a avaliação da condição dependente seja significativa.

Nesse caso, a condição dependente deve ser colocada após o operador && para evitar erros.

Considere a expressão (i != 0) && (10 / i == 2). A condição dependente (10 / i == 2)deve appear afterao &&operador para evitar a possibilidade de divisão por zero.

outro exemplo (myObject != null) && (myObject.getValue() == somevaluse)

e outra coisa: &&e ||são chamados de avaliação de curto-circuito porque o segundo argumento é executado ou avaliado, only ifo firstargumento faz not sufficecom determineo valuedoexpression

Referências: Java ™ Como Programar (Objetos Antigos), Décima Edição

Basheer AL-MOMANI
fonte