Curto-circuito do operador lógico de Java

Qual conjunto está causando curto-circuito e o que exatamente significa que a expressão condicional complexa está causando curto-circuito?

public static void main(String[] args) { int x, y, z; x = 10; y = 20; z = 30; // TT // TF // FT // FF //SET A boolean a = (x < z) && (x == x); boolean b = (x < z) && (x == z); boolean c = (x == z) && (x  z); //SET B boolean aa = (x < z) & (x == x); boolean bb = (x < z) & (x == z); boolean cc = (x == z) & (x  z); } 

    O && e || operadores “curto-circuito”, o que significa que eles não avaliam o lado direito se não for necessário.

    O & e | operadores, quando usados ​​como operadores lógicos, sempre avaliam os dois lados.

    Há apenas um caso de curto-circuito para cada operador e eles são:

    • false && ... – não é necessário saber qual é o lado direito, o resultado deve ser false
    • true || ... true || ... – não é necessário saber qual é o lado direito, o resultado deve ser true

    Vamos comparar o comportamento em um exemplo simples:

     public boolean longerThan(String input, int length) { return input != null && input.length() > length; } public boolean longerThan(String input, int length) { return input != null & input.length() > length; } 

    A segunda versão usa o operador não-curto-circuito & e lançará um NullPointerException se a input for null , mas a primeira versão retornará false sem uma exceção;

    O SET A usa operadores booleanos de curto-circuito.

    O que significa “curto-circuito” no contexto dos operadores booleanos é que, para um conjunto de booleanos b1, b2, …, bn, as versões de curto-circuito cessarão a avaliação assim que a primeira dessas booleanas for verdadeira (|| ) ou falso (&&).

    Por exemplo:

     // 2 == 2 will never get evaluated because it is already clear from evaluating // 1 != 1 that the result will be false. (1 != 1) && (2 == 2) // 2 != 2 will never get evaluated because it is already clear from evaluating // 1 == 1 that the result will be true. (1 == 1) || (2 != 2) 

    Curto-circuito significa que o segundo operador não será verificado se o primeiro operador decidir o resultado final.

    Por exemplo, a expressão é: True || Falso

    No caso de ||, tudo o que precisamos é de um lado para ser Verdadeiro. Portanto, se o lado esquerdo for verdadeiro, não faz sentido verificar o lado direito e, portanto, isso não será verificado.

    Da mesma forma, False e True

    Em caso de &&, precisamos que ambos os lados sejam verdadeiros. Portanto, se o lado esquerdo for Falso, não faz sentido verificar o lado direito, a resposta tem que ser Falso. E, portanto, isso não será verificado em tudo.

     boolean a = (x < z) && (x == x); 

    Este tipo entrará em curto-circuito, significando que se (x < z) falso, então o segundo não é avaliado, a será falso, caso contrário, && também avaliará (x == x) .

    & é um operador bit a bit, mas também um operador AND booleano que não causa curto-circuito.

    Você pode testá-los por algo da seguinte maneira (veja quantas vezes o método é chamado em cada caso):

     public static boolean getFalse() { System.out.println("Method"); return false; } public static void main(String[] args) { if(getFalse() && getFalse()) { } System.out.println("============================="); if(getFalse() & getFalse()) { } } 

    Em termos simples, o curto-circuito significa interromper a avaliação quando você sabe que a resposta não pode mais mudar. Por exemplo, se você estiver avaliando uma cadeia de ANDs lógicos e descobrir um FALSE no meio dessa cadeia, saberá que o resultado será falso, não importando quais são os valores das demais expressões da cadeia. . O mesmo vale para uma cadeia de OR : uma vez que você descobre um TRUE , você sabe a resposta imediatamente, e assim você pode ignorar a avaliação do resto das expressões.

    Você indica ao Java que você quer um curto-circuito usando && invés de & e || em vez de | . O primeiro conjunto no seu post está em curto-circuito.

    Note que isso é mais do que uma tentativa de economizar alguns ciclos de CPU: em expressões como esta

     if (mystring != null && mystring.indexOf('+') > 0) { ... } 

    curto-circuito significa uma diferença entre a operação correta e uma falha (no caso em que mystring é nulo).

    Java fornece dois operadores booleanos interessantes que não são encontrados na maioria das outras linguagens de computador. Essas versões secundárias de AND e OR são conhecidas como operadores lógicos de curto-circuito . Como você pode ver na tabela anterior, o operador OR resulta em verdadeiro quando A é verdadeiro, não importa o que seja B.

    Da mesma forma, o operador AND resulta em falso quando A é falso, não importa o que B seja. Se você usar o || e && formulários, em vez do | e & formulários desses operadores, o Java não se preocupará em avaliar o operando direito sozinho. Isso é muito útil quando o operando à direita depende de o da esquerda ser verdadeiro ou falso para funcionar corretamente.

    Por exemplo, o seguinte fragment de código mostra como você pode aproveitar a avaliação lógica de curto-circuito para ter certeza de que uma operação de divisão será válida antes de avaliá-la:

     if ( denom != 0 && num / denom >10) 

    Como a forma de curto-circuito de AND ( && ) é usada, não há risco de fazer com que uma exceção de tempo de execução seja dividida por zero. Se esta linha de código foi escrita usando o único & versão de AND, ambos os lados teriam que ser avaliados, causando uma exceção de tempo de execução quando denom é zero.

    É prática padrão usar as formas de curto-circuito de AND e OR em casos que envolvem lógica Booleana, deixando as versões de caractere único exclusivamente para operações bit a bit. No entanto, existem excepções a esta regra. Por exemplo, considere a seguinte declaração:

      if ( c==1 & e++ < 100 ) d = 100; 

    Aqui, usando um único & garante que a operação de incremento será aplicada a e se c é igual a 1 ou não.

    OU lógico: – retorna verdadeiro se pelo menos um dos operandos for avaliado como verdadeiro. Ambos os operandos são avaliados antes de aplicar o operador OR.

    Curto Circuito OU: – se o operando do lado esquerdo retorna verdadeiro, ele retorna verdadeiro sem avaliar o operando do lado direito.

     if(demon!=0&& num/demon>10) 

    Como a forma de curto-circuito de AND (&&) é usada, não há risco de causar uma exceção de tempo de execução quando demon é zero.

    Ref. Quinta Edição Java 2 por Herbert Schildt

    Existem algumas diferenças entre os operadores & e && As mesmas diferenças se aplicam a | e || . A coisa mais importante a ter em mente é que && é um operador lógico que só se aplica a operandos booleanos, enquanto & é um operador bit a bit que se aplica a tipos inteiros bem como booleanos.

    Com uma operação lógica, você pode fazer um curto-circuito porque, em certos casos (como o primeiro operando de && sendo false , ou o primeiro operando de || sendo true ), você não precisa avaliar o resto da expressão. Isso é muito útil para fazer coisas como verificar null antes de acessar um arquivo ou método e verificar zeros em potencial antes de dividi-los. Para uma expressão complexa, cada parte da expressão é avaliada recursivamente da mesma maneira. Por exemplo, no seguinte caso:

     (7 == 8) ||  ( (1 == 3) && (4 == 4))
    

    Apenas as partes enfatizadas serão avaliadas. Para calcular o || , primeiro verifique se 7 == 8 é true . Se fosse, o lado direito seria totalmente ignorado. O lado direito só verifica se 1 == 3 é false . Como é, 4 == 4 não precisa ser verificado, e toda a expressão é avaliada como false . Se o lado esquerdo fosse true , por exemplo, 7 == 7 vez de 7 == 8 , todo o lado direito seria ignorado porque o conjunto || expressão seria true independentemente.

    Com uma operação bit a bit, você precisa avaliar todos os operandos porque você está apenas combinando os bits. Os booleanos são efetivamente um inteiro de um bit em Java (independentemente de como os internos funcionam), e é apenas uma coincidência que você pode fazer um curto-circuito para operadores bit-a-bit nesse caso especial. A razão que você não pode curto-circuito um inteiro geral & ou | A operação é que alguns bits podem estar ativados e alguns podem estar desativados em qualquer operando. Algo como 1 & 2 produz zero, mas você não tem como saber isso sem avaliar os dois operandos.