Operadores booleanos a diferença entre os operadores lógicos short-circuit (&& e ||) e bit-wise( &,

Pessoal,

Estou com dúvidas em relação aos operadores booleanos “short-circuit” ( && e || ) e “bit-wise” ( &, ! e ^ ).

1a dúvida) Quais as principais diferenças entre eles ?
2a duivda) Eles só podem ser utilizados com tipos Booleanos ou também podem ser usados com tipos Integrais ?
3a dúvida) Quando devemos utilizar um “short-circuit” ?
4a dúvida) Quando devemos utilizar um “bit-wise” ?

Agradece,

Max Carvalho

Antes de tudo, vamos esclarecer uma coisa.

O java tem operadores lógicos e operadores bitwise.

Os operadores lógicos só trabalham com boolean, e podem ou não apresentar a característica de short circuit. São eles
&& (e) || (ou) ! (not) & (e, sem short circuit), | (ou, sem short circuit)

Os operador bitwise trabalham com tipos integrais. O que eles fazem, é comparar cada bit dos dois integrais passados, usando a operação desejada. São eles:
& (e) | (ou) ^ (ou exclusivo, XOR) ~ (NOT)

Embora os operadores & e | sejam iguais, note que eles mudam de função de acordo com o contexto.

Ou seja:
boolean x = a | b;

É diferente de:
int x = a | b;

Agora, vamos lá, o que é a característica do curto-circuito?
Curto-circuito evita que parte da expressão seja avaliada, caso o resultado dela já seja conhecido. Lembre-se da tabela verdade:
Verdadeiro OU QualquerCoisa = Verdadeiro
Falso E QualquerCoisa = Falso

Se inverter os termos isso também vale, mas o Java avalia da direita para a esquerda. Ou seja, suponha que você tenha:
if (idade >= 18 && mediaDosAlunos() < 5)
facaAlgo();

Haveria necessidade de calcular a média dos alunos, caso a idade fosse < 18? Não, a condição se tornaria falsa e, como temos um E, temos CERTEZA que, independente da média, o resultado da expressão será falso, e o programa não entrará no IF. Da mesma forma:

if (idade >= 18 || mediaDosAlunos() < 5)
facaAlgo();

Não haveria necessidade de calcular a média, caso a idade fosse >= 18. Como a primeira parte da expressão seria verdadeira, independente da média, entraríamos no IF, já que se trata de um ou. Com a opção de curto circuito, o Java efetivamente não irá chamar o método mediaDosAlunos(). Se você usar o operador sem curto circuito, ele irá chamar, avaliar aquele lado da expressão, mas o resultado será o mesmo.

Em geral, não temos razões para eliminar o curto circuito. Eu mesmo, nunca precisei.

Agora vamos as operações bitwise. O que elas fazem é realizar E, OU, etc, nos vários bits de um número integral.
Suponha:
int x = 10 = 1010
int y = 7 = 111

x & y =
1010 &
0111

0010

x | y =
1010 |
0111

1111

Entendeu?

Obrigado pela explicação.
A propósito, não me recordo também quais são os operadores Java para deslocamento e rotação de bits, à esquerda e a direita.
Agradece,

Max Carvalho

http://java.sun.com/docs/books/tutorial/java/nutsandbolts/op3.html

Quase esqueço de comentar. Note que o curto-circuito permite simplificar ifs. Por exemplo:

public void setNome(String nome) { if (nome == null || nome.trim().size() == 0) throw new IllegalArgumentException("Informe um nome!"); this.nome = nome.trim(); }

Veja o primeiro if. Se nome for null, o curto-circuito entrará imediatamente no if, e lançará uma IllegalArgumentException.

Agora imagine o que ocorreria sem o curto-circuito, quando o Java tentaria avaliar o segundo lado da expressão.
Como a variável seria nula, uma NullpointerException seria lançada ao chamar o método trim(). Isso não é de longe o que esperamos ali.

O curto-circuito com o operador ||, nesse caso, nos dá a segurança de que o segundo lado só será avaliado caso o primeiro seja falso. Algo extremamente desejável nesse caso.