Quando utilizar short circuit em Java

(Last Updated On: 16 de Maio de 2016)

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 os cursos de certificação Java no Alura, com 9 cursos especializados para você se preparar para a certificação da Oracle!

FIQUE POR DENTRO

Content Editor at Alura and Software Developer

  • Leonardo Santos

    Cara, &, ^ e | são operadores para manipulação de bits, isso é bem diferente dos operadores lógicos, acho que você deveria dar uma pesquisada nisso.

    & é o operador AND;
    | é o operador OR;
    ^ é o operador XOR;

    Alguns exemplos de uso;
    5 & 6; // é igual a 4 pois 00000101 & 00000110 é 00000100
    5 | 6; // é igual a 7 pois 00000101 | 00000110 é 00000111
    5 ^ 6; // é igual a 3 pois 00000101 | 00000110 é 00000011

    • Leonardo Santos

      Correção no ultimo, é 00000101 ^ 00000110 é 00000011

    • Olá Leonardo, realmente eu me expressei errado quando falei de operadores lógicos para o bitwise, porém, eu já ajustei no post. Obrigado por avisar 🙂

Próximo ArtigoLinux: compactando e descompactando arquivos com o tar