Alura > Cursos de Programação > Cursos de Java > Conteúdos de Java > Primeiras aulas do curso Certificação Java SE 7 Programmer I: Operadores

Certificação Java SE 7 Programmer I: Operadores

Use operadores Java - Introdução

Nessa seção nós vamos aprender a usar os operadores. A prova vai cobrar de nós um uso dos operadores do Java. A primeira coisa, vou criar uma classe nova. Essa minha classe vai chamar TestaOperadores. Dentro dessa classe vou testar meus operadores. O primeiro e mais importante de todos é o operador de atribuição, eu quero pegar um valor, seja um valor do tipo primitivo ou uma referência para um objeto e atribuir para alguém.

No Java, qual o operador de atribuição? O operador de atribuição no Java é o igual. E como eu uso o operador de atribuição? Uma das maneiras tradicionais é declarar uma variável e atribuir um valor a ela. Então eu posso, por exemplo, escrever long idade =;. O que eu estou atribuindo? Se eu estou atribuindo alguma coisa, preciso de alguma coisa do lado direito do operador, que é o que você vai colocar no lado esquerdo, na variável, na coisa referenciada do lado esquerdo.

Do lado direito, o que vou atribuir, e no lado esquerdo onde vou atribuir. Óbvio, se eu tentar compilar isso, eu vou compilar e ele vai falar que não deu certo. Eu preciso de uma expressão aqui. No começo, logo depois do igual eu precisava de uma expressão dizendo o que eu quero atribuir para o lado esquerdo. Um valor literal, uma expressão, alguma coisa eu precisava aqui, e não tem nada. Qual a idade que você quer colocar aí?

Eu posso colocar uma idade, por exemplo, long idade = 15. Da mesma maneira, não funcionaria se eu declarasse a variável sem nome, não faz sentido declarar uma variável, você está falando o tipo dela, e não está falando o nome. Eu quero atribuir o valor 15 ali, não faz sentido algum, assim como não faz sentido algum só um igual voando. Tudo isso não compila.

O que compila é declarar uma variável e atribuir um valor a ela. Óbvio, eu posso declarar a variável e depois atribuir um valor a ela, também é uma opção, mas o operador de atribuição é o operador igual, preciso de alguma coisa na direita, que é o que eu vou atribuir, e no lado esquerdo, que é onde eu vou atribuir.

Sempre que eu vou fazer uma atribuição, a atribuição funciona, ela é compilada se o valor que está agindo, isso é, a expressão que eu quero atribuir, o resultado da expressão que quero atribuir que está do lado direito for um tipo menos abrangente do que o do lado esquerdo.

Por exemplo, aqui eu tenho um int e do lado esquerdo eu tenho um long. Esse cara é menos abrangente, cabe menos coisa, ele é mais específico do que um long, que é mais genérico, cabe mais coisa, ele suporta mais coisas dentro dele. Então eu posso colocar um int dentro de um long, não tem problema.

Nós mostramos que o int é um 15, só fazendo uma atribuição direta de 15 para i, então os dois são ints, estou feliz e contente, nesse caso não, nesse caso estou falando, pega um valor que é mais específico, menos abrangente, e coloca dentro de um cara mais abrangente, que cabe mais coisa, que suporta mais coisa do que eu tenho do lado direito, que é só um int.

Então quando formos fazer a prova e estivermos olhando essas atribuições que ele está fazendo de tipos primitivos, por exemplo, sempre temos que lembrar aquela história do tamanho dos tipos primitivos. Qual o menor de todos eles? Byte, depois short, depois int, depois long. O char tem o mesmo tem que o short, mas o char só pode ser positivo, e o short é positivo e negativo.

Depois eu tenho o double e o float, que são pontos flutuantes, o float é menor que o double, tem menos precisão do que o double. Então é só pensarmos aqui diversos exemplos, tentar passar uma variável de um tipo para outra e ver se posso ou não posso nessa minha tabela byte para short para int para long, um long pode receber um int, não tem problema nenhum, float para double pode receber, não tem problema nenhum.

Outra coisa é que todos esses caras aqui cabem em um float e um double, porque posso pegar o número 15 e colocar em um float, ou em um double, não tem problema nenhum, você vai ter uma questão de precisão aí, não tem problema. E o char temos que tomar sempre alguns cuidados porque ele só é positivo.

Alguns exemplos, int a = 10, maravilha. O que mais? Além do a igual a 10, porque estou pegando um int, colocando int não tem problema, b igual a 20 também não tem problema, pegando um int e colocando em um double, não tem problema, menos abrangente para mais abrangente.

O que mais? Vou criar um short agora, short c = 3, um número short, não tem problema nenhum. Lembra que quando colocamos um valor literal que cabe dentro de um short o Java vai automaticamente fazer a conversão para o short para nós, não precisa se preocupar. A mesma coisa para o byte, byte d = 4, não tem problema, ele automaticamente converte. Isso no caso de valores literais.

Vamos compilar esse cara. Eu compilo, tudo ok, a atribuição maravilha desses caras. Agora e se eu pegar os caras com ponto flutuante? Por exemplo, um double e igual a 30.0. Não tem problema nenhum, é um double. Um float f igual a 40.3, não tem problema nenhum.

Agora, como é que eu faço para pegar um float e colocar em um double, afinal o float é menor que o double, vou criar um float, isso é, 40.3f, e vou colocar ele em um double, será que tem problema? Tento compilar. Não tem problema. Float cabe dentro de um double.

E aquela história que eu falei, tanto byte, short, int, long podem ser colocados dentro de um float, podem ser colocados dentro de um double também, então vou fazer f = a, isso é, estou colocando um valor int dentro dele, f = b, estou colocando um long dentro dele, f = c, estou colocando um short, estou colocando um valor que era referenciado pelo short, o valor estou short dentro do meu float.

Será que todos esses caras compilam? Vou compilar e todos eles ok. O ponto é que se por algum acaso o Java não conseguisse representar precisamente esse número, você perderia precisão, por isso você consegue receber qualquer tipo de inteiro dentro de um float.

A mesma coisa para o double, igual a a, igual a b, igual a c, e igual a d. Ele pode receber qualquer um deles. Se der alguma falha na hora de representar, ele não conseguirá representar exatamente aquele número, azar o teu, mas consegue atribuir, porque ponto flutuante você não tem certeza que ele vai representar exato. Ele representa com ponto flutuante.

O caminho contrário, no compilador não vai gostar. Se eu tentar pegar um cara grande e colocar em um cara pequeno, por exemplo, pegar um long e coloco no int, isso é, pega esse long b e coloca no a, você está pegando um long e colocando no a? Acho que não vai deixar, porque o long pode ser um número que não cabe dentro do int, não vai rolar.

E se eu tentar pegar então esse meu int e colocar no short? Eu compilo e ele de novo reclama. E se eu pegar meu short e colocar no byte? Eu compilo e de novo reclama. Não posso pegar um cara maior e colocar no menor. A mesma coisa do ponto flutuante para o inteiro, não adianta eu querer falar para pegar esse double bonito que eu tenho aqui e tentar colocar ele dentro do nosso byte.

Não sei se vai rolar, não deve rolar, porque não tem, você vai perder precisão, possivelmente perder precisão. Não pode fazer isso. Se nós quisermos fazer isso até vamos poder daqui a pouco, mas por padrão não compila. O que compila é um tipo menos abrangente, cabe menos coisa, para um tipo mais abrangente, que suporta mais coisa. E lembrando que a única exceção são os casos dos literais do short, byte e o caso que eu comentei agora, o char.

Se eu quiser colocar um char h = 65 eu posso colocar, um número válido. 65 é um número entre 0 e 65 mil e alguma coisa, não precisa saber o número exato, tudo bem, ele compila. Só que se eu colocar um número inválido aqui, -2, aí tudo bem. A mesma coisa para o byte. O byte não é -120 alguma coisa? Se eu colocar -200 ele não deixa, ele se toca desse meu erro.

Agora, se eu colocar o 4 ele deixa e fica feliz e contente. Então ele valida o literal. O valor do literal. Agora se eu tentar aplicar de um cara maior para um menor, não posso, simplesmente diretamente, e se eu aplicar de um cara menor para um cara maior, joia, ficamos felizes e contentes. E o short para o char, afinal o short e o char tem o mesmo tamanho no Java, será que eles fazem a conversão? Será que se eu pegar o short e colocar dentro de um char funciona?

Mas o short não pode ter valores negativos? Você pode estar perdendo precisão, Guilherme. E o contrário, e se eu pegar um char que é sempre positivo e colocar dentro de um short, será que eu posso? Aí eu tento de novo e também não posso. Possível precisão.

Imagina se aquele número fosse negativo, ou se aquele número fosse positivo, além de estourar, não dava. Não cabe dentro do outro, se não cabe dentro do outro, não vou poder. A sacada é decorar a tabela. Eu posso converter byte para short, short para int, sem problema nenhum. Eu posso converter byte para short, short para int, sem problema nenhum, posso converter float para double, sem problema nenhum, inteiro para ponto flutuante sem problema nenhum.

Char eu posso converter, ele entra aqui no int, char eu posso converter para int e para long, não tem problema nenhum. Agora, o caminho contrário não pode. Você tem uma variável, um resultado de uma expressão que é de um tipo maior para um tipo menor, não vai compilar. Aí o que eu posso fazer é usar um valor literal. Como usamos no short, no byte e no char.

Nós usamos um valor literal, que seria um inteiro, mas o Java é esperto, ele é gente boa, ele olha o compilador, olha o valor literal, vê que cabe, se cabe ele coloca lá dentro, se pode ser representado ele coloca lá dentro.

Ainda falando do operador de atribuição, eu tenho que pensar em um outro caso, eu tenho os tipos primitivos, todos esses caras que são numéricos, e tenho o boolean, que atribui normalmente como uma variável primitiva qualquer. Atribui o boolean só de true e false para boolean, ou o resultado de uma expressão booleana para boolean.

E no caso que é uma referência, referência para objetos. Eu tenho que lembrar que quando eu trabalho com objetos e referências para objetos a atribuição é por referência, e não valor, conforme nós sempre vemos, referência e valor são coisas diferentes. Quando trabalhamos com tipos primitivos é valor, quando trabalhamos com referências é referências.

Então, se o que tenho aqui é uma referência para uma Java.util.ArrayList, então vou pegar uma array list e crio essa minha array list de string lista igual a new ArrayList de string usando o nosso generics, posso criar essa lista e não tem problema nenhum, fica tudo funcionando.

Eu posso usar também a atribuição lista2 igual a lista. Atribuí a referência àquela lista original a essa segunda variável, as duas variáveis estão apontando, referenciando o mesmo objeto em memória. Importantíssimo de lembrar, quando trabalhamos com objeto trabalhamos com referências, com ponteiros, referências para aquele objeto na memória.

Agora, quando estou trabalhando com a atribuição de referências eu posso usar o polimorfismo, que vamos ver com bastante calma no capítulo de polimorfismo, mas é importante lembrar que a atribuição vai suportar o polimorfismo. Então, por exemplo, como a array list implementa a interface list, se eu importar tanto ela quanto a interface list, eu posso falar que essa lista é uma list de string, porque esse cara é o menos abrangente. Array list é mais específico, é menos abrangente. List é mais genérico, é mais abrangente, é a classe pai, a classe mãe, etc. Ela é mais genérica, mais abrangente.

Então eu posso atribuir do menos abrangente para o mais abrangente, não tem problema, funciona. No caso do Java 7 em diante eu posso usar até o operador diamante que nós falamos, que tiramos a palavra string daqui e induz, quando ele está compilando ele percebe, você está criando um novo ArrayList de que mesmo? Ah, você quer um array list de string, então se você dá um new direto e atribui ele a uma variável, o próprio compilador vai perceber que essa array list é de string, a partir do Java 7, e aí ele já cria um array list do tipo string e tudo funciona.

Vamos compilar? Compilo. Maravilha, tudo compilando. Então o que eu tenho que tomar cuidado com o operador como referência é lembrar que operador de atribuição com referência copiando a referência, são duas variáveis referenciando o mesmo objeto em memória. Essa é a importância do operador de atribuição com referência.

Nos outros casos estamos sempre copiando o valor, e em todos os casos a regra que funciona é do tipo menos abrangente para o tipo mais abrangente, ficamos felizes e contente. Do tipo mais abrangente para o menos abrangente, não compila por padrão, e no caso dos literais, byte, chat e short não precisa se preocupar que ele vai fazer, nos casos dos literais byte, short e char, ele vai verificar se o número que você está passando é um número válido em tempo de compilação.

Operadores aritméticos - Operadores Aritméticos

Continuando com os nossos operadores, agora é a hora dos operadores aritméticos. Vou criar um novo arquivo, que vai se chamar TestaAritmetica.java, class TestaAritmetica public static void main(String[] args). E aqui dentro o que vou fazer? Muita conta, muita conta.

Primeira coisa vou criar dois números, o número dois e o número dez. Olha que bonito, número dois e número dez estão criados. Então o Java define operadores aritméticos para aquelas principais operações aritméticas, aquelas cinco tradicionais ele vai ter, soma, subtração, multiplicação, divisão e resto de divisão, cociente e resto. E vai ter também outros operadores, que podemos acabar utilizando.

Vamos lá, a primeira coisa é o operador de soma, int doze = dez + dois, óbvio, dez mais dois é doze, operador de soma. Oito é igual a dez menos dois, maravilha, operação de subtração. Vinte igual a dez vezes dois, dez vezes dois é vinte. E por fim int cinco = dez / dois, esses são os valores e operações que posso fazer com soma, subtração, multiplicação e divisão. São os quatro principais, na verdade.

Então vou compilar, javac TestaAritmetica.java. Está compilando. E eu falei que tem um quinto operador de operação aritmética tradicional, que é o de resto. Assim como tive o quociente da divisão, que foi cinco, eu posso ter o resto da divisão. Então coloco aqui que o resto da divisão, quanto é o resto da divisão de cinco por dois? Cinco resto da divisão por dois. Resto um, certo? Então o valor desse cara é um, o resto da divisão por dois.

Então o resto da divisão é o que chamamos de mod, é o porcento no Java. Mas a prova vai cobrar quanto é oito mais dois, quanto é dez menos dois? Não, ela não vai cobrar exatamente isso. O que ela vai tentar cobrar de nós é saber quando eu faço uma operação aritmética qual é o tipo retornado por essa operação aritmética. E para sabermos isso temos que dar uma olhada no tipo dos dois caras que estamos usando nessa operação aritmética.

E tem uma regra geral. A regra geral é que ele vai devolver no mínimo um int, no mínimo um int, não vai devolver byte, não vai devolver char, não vai devolver shot, vai no mínimo um int. E o que ele vai devolver exatamente seria um maior dos dois tipos envolvidos.

Então se eu tenho, por exemplo, um int e outro int, ele vai devolver um int, os dois são ints. Se tenho um int e um long, o que ele vai devolver? O maior dos dois é um long, então ele vai devolver um long. Vamos ver isso acontecer? Vamos mudar essa variável dez para long e vou tentar compilar.

Ele fala um monte de erro. Qual é o erro? Nós estávamos querendo atribuir um long para um int, mas então aqui do lado direito você precisava ter um int se você está querendo ter um int. Eu estava requerendo um int, mas eu encontrei um long do lado direito, porque o resultado dessa operação é um long.

Então agora o que vou fazer? Ao invés de usar um long vou colocar um int aqui. Agora tenho dois ints, a operação resultado é um int. Lembra que ele vai pegar sempre um maior. Então se faço uma operação int int dá int, int long dá long, long long dá long.

Agora e se eu faço uma operação com dois bytes? Você lembra que eu falei que o byte quando temos o valor literal ele sabe se virar, mas quando faço a conta com ele, cuidado, o mínimo que uma operação aritmética devolve é um int, então ele vai devolver um int para nós.

Se eu compilar isso, claro, compila, porque ele está devolvendo um int e eu estou criando uma variável do tipo int, bonito. Mas se eu pegar dois bytes e fazer uma soma, lembra que ele vai devolver um int. Isso na direita é um int. Se eu jogar isso para um byte eu posso atribuir um int para um byte? Lembra da tabela, int é maior do que byte, cabe mais coisa do que byte, não pode atribuir. Vou tentar e ele fala que você está perdendo precisão.

Eu estava querendo um byte e você está me dando um int, int para byte não vai rolar. Volto atrás e deixo esse cara como int assim como esses outros dois caras vão ser int. Então nos tipos primitivos que são inteiros, a regra geral é essa. Um mínimo ele vai devolver um int, e ele vai devolver na verdade o maior dos dois tipos. Mas e se eu envolver um float no meio, põe um ponto flutuante para ver o que acontece.

Vou colocar um float. Aí a pergunta, quem é maior, int ou float? Lembra da tabela de novo? Do int para o float flui naturalmente, porque o float tem a capacidade de armazenar várias coisas com uma precisão questionável, mas ele armazena os números do int, então quando eu fizer a conta do float com int ele vai devolver um float para nós.

E se eu tentar pegar um float e colocar no int, vai perder precisão. E se esse número for 2.00001? Perdeu precisão, o compilador não vai deixar você fazer isso. Vou tentar compilar. Ele fala, você possivelmente está perdendo precisão, você está falando que a variável vai ser um int, mas a variável é um float que você está me devolvendo, não pode.

A mesma coisa para o double. Se eu pegar um double aqui, qual dos dois é maior, o int ou o double? Double é maior, então essa operação aritmética vai devolver double. Se a operação aritmética devolver um double, tento atribuir para um int, não pode. Não vou deixar. E aí dá erro de novo.

Então lembrar da tabela, você vai estar sempre com o maior dos tipos e no mínimo vai ser um int. Importantíssimo lembrar esse caso. Um outro caso importante é a divisão por zero. Se eu fizer uma divisão por zero, o que acontece? Vamos testar. Dois casos diferentes.

Um primeiro caso vou testar cinco dividido por zero, vamos ver quanto dá, int divisao1 = 5 / 0, vamos compilar. E rodo. Aritmética exception, divisão por zero. Não pode dividir um número inteiro por zero. Por que não pode dividir um número inteiro por zero? Porque isso não existe, não existe cinco dividido por zero, então um número inteiro dividido por zero não pode, vai dar um erro de execução.

Agora, e se eu dividir cinco por 0.0? Eu estou dividindo um int por um double, o que uma divisão, operação aritmética de int e double devolve? Double. Então isso nem devia compilar. Vamos tentar. Não compila, porque você pode estar perdendo precisão, tem que declarar a variável como double.

Eu vou lá e declaro a variável como double, compilo de novo, compilando, que nem compilava antes. Vou rodar. Divisão por 0.0 existe. Quando falamos de ponto flutuante, divisão por 0.0 existe. Ou se eu fizesse o contrário, fizesse 5.0 dividido por 0 existe, porque estou fazendo uma divisão de números com ponto flutuante. Converte um outro número que seja qual for para ponto flutuante e faz a divisão, divisão por zero e ponto flutuante existe, e se é esse caso, um número positivo por zero ponto flutuante, o número é bem engraçado.

O número que vai dar aqui é infinito. Nós não precisamos decorar que vai dar infinito, ou decorar que se eu dividisse -5.0 por 0 dá menos infinito, não precisa decorar isso. Mas precisamos saber que se a divisão for do tipo int ou do tipo long, se ela for uma divisão por zero e números inteiros, vai dar erro no tempo de execução.

Se ela for uma divisão de ponto flutuante por zero não vai dar exception, porque existe uma representação e essa representação é um infinito, menos infinito, etc, essas contas válidas quando falamos de ponto flutuante. E aí muito cuidado, porque a prova vai cobrar de você uma coisa dessa operação meio maluca junto com a divisão por zero, por exemplo, eu posso pegar meu número que é um int e somar 0.0. Quanto é esse cara? É 2.0, tudo bem, mas ele é 2.0, ele virou um double.

Não acontece aqui nenhuma exception. Vamos fazer isso acontecer? Vou tirar a variável e jogar aqui dentro. Quanto é o resultado dessa conta? Dois mais 0.0, isso é, int mais double é double, double dividido por int é double, e existe uma divisão por zero no mundo dos doubles, o mundo dos doubles é o mundo das coisas bonitas que têm infinito, então compila e roda.

Agora se ao invés disso ele só somasse um zero, isso é um int e isso é divisão por zero em int. Então repare que aquele soma de 0.0 faz com que eu não tenha a exception em tempo de execução. Se eu não somo 0.0, se eu só somo zero, aí ele dá a exception em tempo de execução, porque estou trabalhando com ints.

Então cuidado, divisão por zero, ponto flutuante, maravilha, divisão por zero e inteiros não maravilha, exception em tempo de execução. E algumas contas ainda malucas podem dar o not a number, como um número inválido, etc. Vou mostrar um exemplo delas. Seria eu pegar aqui o positivo infinito e somar com o negativo infinito. Isso aqui é um número indefinido na matemática quando estamos falando de double.

Se eu fizer aqui um double positivo infinito que nós já sabemos fazer essa conta, é 5.0 dividido por 0, se eu tiver essa conta e o negativo infinito como sendo -5.0 por 0, comenta essa linha porque daria uma exception e posso tentar rodar. Compilo, e rodo. Ele fala not a number, nan.

Não preciso decorar quando acontece o not a number, o importante mesmo é a divisão por zero, e saber que existe esse outro caso, not a number.

Operadores de comparação - Operadores lógicos

Muitas vezes precisamos trabalhar também com operadores em cima de valores booleanos, por exemplo, eu quero pegar um true e transformar em um false, quero pegar um false e transformar em true, quero fazer uma condição somente duas condições booleanas forem verdadeiras, só se isso e aquilo.

Nessas situações vamos ter os operadores lógicos. Vamos trabalhar com eles? Vou criar minha classe, a classe vai ser TestaOperadoresLogicos. Vamos lá. Agora o que vou fazer aqui dentro é vou querer trabalhar com booleanos. Então, a primeira coisa é que quero imprimir se um é igual a um, isso nós já sabemos, e um maior que dois.

Só se essas duas coisas forem verdadeiras, senão vou imprimir falso. E no Java é &. O que mais? Quero imprimir ou se um é igual igual a um ou um maior do que dois. Se qualquer um dos dois for verdadeiro, é isso, true para mim, senão quero false. Ou no Java é o |.

O que mais? Eu quero agora fazer com que seja somente se um for verdadeiro e o outro falso, ou se esse for falso e o outro for verdadeiro, isso é, exclusivo. O ou exclusivo é System.out.println(1 == 1 ^ 1 > 2). O ou exclusivo é o chapeuzinho, circunflexo, o chapeuzinho circunflexo é o ou exclusivo. Isso é, se esse for verdadeiro e esse for verdadeiro, eu quero que seja ou exclusivo, não os dois ao mesmo tempo.

Então se os dois forem verdadeiro, ou se os dois forem falsos, dá falso. Se qualquer um dos dois for verdadeiro e o outro for falso, verdadeiro, esse é o ou exclusivo. E por fim, a negação. System.out.println(!(1 == 1)), eu quero negar isso, exclamação. Vou colocar entre parênteses, senão ele ia aplicar essa exclamação no meu número um, não fazia sentido.

Então pega esse resultado que é true e transforma em false. Se esse resultado fosse false ele transformava em true. Eu inverto, é a negação. Vamos testar? Vou compilar.

False, true, true, false. O primeiro é false? Sim, os dois não são verdadeiros. O segundo é true, porque o primeiro é verdadeiro, já é o suficiente. O outro não estou nem aí. Terceiro é verdadeiro, porque um deles é verdadeiro e o outro é falso, não me importa qual é qual, e o quarto é true vira false, virou false. Estou com todos os meus operadores lógicos que eu queria mostrar aqui, esses quatro operadores lógicos.

Só que repara que quando eu fui executar esse caso do ou, quando ele viu que um era igual igual a um, ele já sabia que isso ia ser verdadeiro, não me importava o lado da direita, mesmo assim o Java vai compilar, vai executar esse lado da direita. Se eu quiser fazer um short-circuite, se eu já sei que isso vai dar true ou se eu já sei que isso vai dar false, não precisa executar o lado lá da direita, eu vou usar ao invés de um pipe dois pipes, a mesma coisa para o &.

Nesse caso, o que estou falando é quando eu evaluar, quando eu executar o passo da esquerda e eu já descobri o valor porque não faz diferença o lado da direita, nem precisa executar o lado da direita. Por exemplo, nesse caso vai acontecer isso, porque esse é true, então não importa o ou. Já que é ou e o primeiro é true, vai ser true, não me importa o que tem na direita.

Que outro exemplo seria o exemplo equivalente no &? Seria o diferente. Nesse caso já é falso, se já é falso, o & não importa o que estiver na direita. Falso e qualquer coisa vai ser falso, então ele nem executa o lado da direita. Parece ser bobo, vamos tentar executar e ver o que acontece.

Falso, falso, true. Falso, porque isso era falso mesmo, esse também é falso porque é falso, então ele já para por aí, e true porque esse cara já é true, ele para por aí mesmo. Agora, quando isso vai fazer bastante diferença para mim e a certificação pode me encher a paciência nisso?

É quando eu usar esses dois caras, o short-circuit e do meu lado direito eu chamar um método. Por exemplo, o primeiro. Ou método segundo. Ou método terceiro. Então vou criar esse método, public, eu estou no escopo estático, vou criar um método estático, vamos falar sobre coisas estáticas depois com calma, aqui estou só criando esse meu método, então return System.out.println(msg) e vou retornar para ele sempre true.

Ao invés de void, boolean. Então o que estou fazendo aqui? Estou falando faz essa comparação e esse cara for verdadeiro. Esse método sempre devolve verdadeiro. Esse cara aqui e for verdadeiro. Esse cara ou o da direita for verdadeiro. Vamos tentar executar e ver o que acontece?

Vou lá no meu programa, compilo e rodo. Deu primeiro true, false, true, cadê o segundo e terceiro? Vamos dar uma olhada? O que ele fez? Um igual igual a um, true, e o segundo, preciso executar o segundo, certo? Porque para o e ser verdadeiro os dois lados têm que ser verdadeiros, então tenho que executar o primeiro e executar o segundo, então ele chamou o método primeiro, imprimiu a mensagem primeiro, esse cara deu true.

Aí o que ele falou? True e true? Imprime true para mim e imprimiu o true. Maravilha. E no segundo caso? Porque ele não imprimiu a palavra segundo? Porque ele olhou, um é diferente de um? Um é diferente de um? Não. Um não é diferente de um, então isso é false. False e qualquer coisa vai dar false. Então nem precisa executar qualquer coisa. E aí que entra a sacada dos dois &.

Ele nem executa esse método, e aí ele nem imprime segundo. A mesma coisa no terceiro caso. Ele olha, um é igual a um? Verdadeiro. Verdadeiro ou qualquer coisa é verdadeiro, então ele nem executa esse cara. Repare que se eu tirasse daqui e fizesse sem o short-circuit o que ia acontecer? Compilo e rodo. Olha a diferença.

Ele imprimiu o segundo, ele imprimiu o terceiro, porque sem o short-circuit ele sempre executa os dois lados. Com o short-circuit ele tenta executar o primeiro, vê o resultado, se o resultado é suficiente ele para por aí. Se não é o suficiente ele executa o segundo.

E está aí o nosso short circuit. O short circuit não existe uma versão para o ou exclusivo, porque o ou exclusivo sempre tem que executar os dois lados, se esse é true esse tem que ser false e se esse é false esse tem que ser true, então o ou exclusivo não existe short circuit.

Sobre o curso Certificação Java SE 7 Programmer I: Operadores

O curso Certificação Java SE 7 Programmer I: Operadores possui 126 minutos de vídeos, em um total de 64 atividades. Gostou? Conheça nossos outros cursos de Java em Programação, ou leia nossos artigos de Programação.

Matricule-se e comece a estudar com a gente hoje! Conheça outros tópicos abordados durante o curso:

Aprenda Java acessando integralmente esse e outros cursos, comece hoje!

Plus

De
R$ 1.800
12X
R$109
à vista R$1.308
  • Acesso a TODOS os cursos da Alura

    Mais de 1500 cursos completamente atualizados, com novos lançamentos todas as semanas, emProgramação, Front-end, UX & Design, Data Science, Mobile, DevOps e Inovação & Gestão.

  • Alura Challenges

    Desafios temáticos para você turbinar seu portfólio. Você aprende na prática, com exercícios e projetos que simulam o dia a dia profissional.

  • Alura Cases

    Webséries exclusivas com discussões avançadas sobre arquitetura de sistemas com profissionais de grandes corporações e startups.

  • Certificado

    Emitimos certificados para atestar que você finalizou nossos cursos e formações.

Matricule-se

Pro

De
R$ 2.400
12X
R$149
à vista R$1.788
  • Acesso a TODOS os cursos da Alura

    Mais de 1500 cursos completamente atualizados, com novos lançamentos todas as semanas, emProgramação, Front-end, UX & Design, Data Science, Mobile, DevOps e Inovação & Gestão.

  • Alura Challenges

    Desafios temáticos para você turbinar seu portfólio. Você aprende na prática, com exercícios e projetos que simulam o dia a dia profissional.

  • Alura Cases

    Webséries exclusivas com discussões avançadas sobre arquitetura de sistemas com profissionais de grandes corporações e startups.

  • Certificado

    Emitimos certificados para atestar que você finalizou nossos cursos e formações.

  • Luri, a inteligência artificial da Alura

    Luri é nossa inteligência artificial que tira dúvidas, dá exemplos práticos e ajuda a mergulhar ainda mais durante as aulas. Você pode conversar com Luri até 100 mensagens por semana.

  • Alura Língua (incluindo curso Inglês para Devs)

    Estude a língua inglesa com um curso 100% focado em tecnologia e expanda seus horizontes profissionais.

Matricule-se
Conheça os Planos para Empresas

Acesso completo
durante 1 ano

Estude 24h/dia
onde e quando quiser

Novos cursos
todas as semanas