Controle de Fluxo com IF contento três condições

Olá pessoal estou estudando para a certificação e na página 187 do livro da Kathy Sierra têm
um exemplo de um IF que retorna false.

[code]int y = 5;
int x = 2;

public boolean doStuff() {
return true;
}

if(( x > 3 ) && ( y < 2 ) | doStuff() ) { //O retorno neste caso aqui é false, inclusive mesmo que a segunda condição fosse true o final da cláusula sairá como false.
System.out.println(“TRUE”);
}[/code]

Até aqui tudo bem, se a primeira condição for false ele não avalia a segunda e sub-entende como se fossem independentes por causa dos parentes.
Então por curiosidade eu resolvi colocar dois pipes na última condição ao invés de um e o retorno do IF foi true. Minha pergunta é alguém saberia me dizer porque acontece isso ?

Fala aí Fernades, bele.

Então se você coloca 2 ||, significa ou, e como o retorno do metodo doStuff é true, será impresso TRUE.

[quote=tiralo]Fala aí Fernades, bele.

Então se você coloca 2 ||, significa ou, e como o retorno do metodo doStuff é true, será impresso TRUE.[/quote]

Acho que a dúvida dele é: pq só com 1 |,não retorna true?

Isso:

 if(( x > 3 ) && ( y < 2 ) || doStuff() )

É igual a isso:

 if((( x > 3 ) && ( y < 2 )) | doStuff() )

Confesso que tbm não lembro o porquê… rs

Blz, então é justamente isso, porque será que o comportamento do IF muda quando se têm um único pipe que neste caso retorna false e quando se têm dois pipes retorna true.
Só para aumentar ainda mais o nível de curiosidade, refiz o mesmo teste no “C” e o comportamento foi igual ao do Java.

[code]int main()
{
int x = 10;
int y = 10;
int z = 5;

if((x > 11) && (y > 9) || z == 5) { //retorna false quando se têm um único pipe
printf("result: %d ", x);
printf(“True\n”);
}
system(“PAUSE”);
return 0;
}[/code]

Esse é efeito é causado por dois fatores:

  • A diferença de funcionamento dos operadores lógicos: && e &, || e |

Os operadores dobrados (&& e ||) são curto-circuitados, ou seja, se a primeira parte da expressão já definir o resultado final, ele nem executa o outro lado da expressão.

  • A ordem de precedência dos operadores.

A precedência do operador && é justamente entre o || e o | na tabela. (Aqui a tabela). Ou seja, a ordem de avaliação das expressões muda quando você usa um pipe ou dois.

Para ver o que o java está fazendo, faça um teste assim:

    public boolean doStuff() {
        System.out.println("doing Stuff");
        return true;
    }

    public int getX() {
        System.out.println("pegando x..");
        return x;
    }

    public int getY() {
        System.out.println("pegando y..");
        return y;
    }

Daí você chama os métodos ao invés das variavéis no if… faça as alterações e veja quais métodos são chamados e em qual ordem.

Sim claro.

AbelBueno falou tudo.

[quote=AbelBueno]Esse é efeito é causado por dois fatores:

  • A diferença de funcionamento dos operadores lógicos: && e &, || e |

Os operadores dobrados (&& e ||) são curto-circuitados, ou seja, se a primeira parte da expressão já definir o resultado final, ele nem executa o outro lado da expressão.

  • A ordem de precedência dos operadores.

A precedência do operador && é justamente entre o || e o | na tabela. (Aqui a tabela). Ou seja, a ordem de avaliação das expressões muda quando você usa um pipe ou dois.

Para ver o que o java está fazendo, faça um teste assim:

    public boolean doStuff() {
        System.out.println(&quot;doing Stuff&quot;);
        return true;
    }

    public int getX() {
        System.out.println(&quot;pegando x..&quot;);
        return x;
    }

    public int getY() {
        System.out.println(&quot;pegando y..&quot;);
        return y;
    }

Daí você chama os métodos ao invés das variavéis no if… faça as alterações e veja quais métodos são chamados e em qual ordem.

[/quote]

Fiz como você falou pra testar, e quando uso um pipe ele só checa o x e saí >.<
Com dois pipes ele checa o X e depois o doStuff…

Sei que os operadores & e | checam as duas operações pra aí sim responder, seria por esse o motivo que o | não segue adiante? já q o && ignora a segunda chamada pq a primeira deu false, o | acaba não sendo chamado pq ele não pode ignorar o q seria a primeira chamada dele???
Tô indo no cmainho certo ou tô viajando ainda mais?