Quando utilizar short circuit em Java
Estou me preparando para a certificação da Oracle e me deparei com a situação de comparação de booleanos. Todas as vezes que precisamos fazer comparações com tipos boolean
utilizamos operadores E ou OU:
System.out.println(1 > 2 & 1 == 1); // false.
System.out.println(1 == 1 | 2 > 1); // true.
Nesses exemplos a comparação é feita nos dois lados. Dois lados? Mas como assim? Isso mesmo, dois lados! Por exemplo:
System.out.println(1 > 2 & 1 == 1);
Quando ele verifica a expressão 1 > 2
é identificado como uma expressão false
, mas, mesmo sabendo que o resultado total será false
, ele verifica o 1 == 1
. Isso significa que sempre que utilizamos esses tipos de operadores a verificação será realizada tanto da condição anterior quanto da posterior! Chamamos esses operadores de _bitwise_ ou então bit a bit.
Agora vamos imaginar uma seguinte situação:
public boolean pagamento(){
pagaTodasAsDividas();
System.out.println("pagamento efetuado");
return true;
}
public boolean temDivida(int tipo) {
// verifica se tem dívida
if (tipo == 1) { System.out.println("tem dívida");
return true; }
else { System.out.println("não tem dívida");
return false;
}
}
if(temDivida(0) & pagamento()){
System.out.println("Comprovante enviado");
}
Testando esse trecho de código:
Resultado:
\> não tem dívida > pagamento efetuado
Como assim pagamento efetuado? Sendo que não tenho dívida... Nesse caso foi feita uma comparação entre dois métodos que retornam boolean
, porém o método pagamento()
possui um efeito colateral e só poderia ser executado se o método temDivida()
retornasse true
... Para resolver esse problema podemos utilizar os operadores short circuit: &&
e ||
. Mas qual seria a diferença? Vamos testar novamente, porém com o short circuit:
if(temDivida(0) && pagamento()){
System.out.println("Comprovante enviado");
}
Verificando o resultado:
\> não tem dívida
Ótimo! Agora se não tiver dívida o pagamento não é realizado! Se testarmos em um momento em que tem dívida, ou seja, quando enviamos 1:
if(temDivida(1) && pagamento()){
System.out.println("Comprovante enviado");
}
Resultado:
\> tem dívida > pagamento efetuado > enviou comprovante
Agora o trecho de código funciona perfeitamente!
Todas as vezes que fazemos uma comparação precisamos tomar certos cuidados ao escolher operadores bitwise (&, | e ^) ou um short circuit (&& e ||). Ao utilizar operadores bitwise corremos um grande risco testando um método que tenha um efeito colateral, como foi o caso do método pagamento()
. A boa prática sugere o uso do short circuit justamente para evitar esse problema.
E aí, gostou do short circuit? Quer aprender mais detalhes da linguagem Java? Pensando nisso, o instrutor Guilherme Silveira criou a formação Java na Alura !