Terceira lição de Java: aprenda a criar decisões com if, else, else if, switch, operadores lógicos e operador ternário.
Java lição 3: Nesta terceira lição da nossa sequência para dominar Java, vamos aprender a fazer o programa tomar decisões.
Até agora trabalhamos com:
- variáveis;
- tipos primitivos;
- operadores aritméticos;
- operadores relacionais;
- operadores lógicos.
Esses conhecimentos serão usados agora para controlar quais instruções devem ou não ser executadas.
O objetivo não é apenas decorar if, else e switch, mas aprender a transformar regras e decisões do mundo real em código Java.
Nesta lição, você aprenderá:
- como funciona o
if; - como usar
ifeelse; - como criar várias decisões com
else if; - por que a ordem das condições importa;
- como combinar condições com
&&,||e!; - como usar condições aninhadas;
- como funciona o
switch; - para que serve o
break; - para que serve o
default; - como utilizar o
switchmoderno; - como um
switchpode produzir um valor; - como usar o operador ternário;
- quando escolher
ifouswitch.
Ao final, criaremos pequenos programas para praticar esses conceitos.
Um programa Java normalmente executa suas instruções de cima para baixo.
Por exemplo:
System.out.println("Linha 1");
System.out.println("Linha 2");
System.out.println("Linha 3");O resultado será:
Linha 1
Linha 2
Linha 3
Mas programas reais precisam tomar decisões.
Por exemplo:
Se a pessoa tiver 18 anos ou mais, permita a entrada.
Ou:
Se o saldo for suficiente, realize o pagamento.
Ou:
Se a nota for maior ou igual a 7, o aluno está aprovado.
É nesse momento que entram as estruturas condicionais.
A palavra if significa:
se.
A estrutura básica é:
if (condicao) {
// código executado se a condição for verdadeira
}Por exemplo:
int idade = 20;
if (idade >= 18) {
System.out.println("Maior de idade");
}A expressão:
idade >= 18produz um valor booleano:
true
ou:
false
Se o resultado for true, o código entre as chaves será executado.
Se for false, o bloco será ignorado.
Observe:
public class TesteIdade {
public static void main(String[] args) {
int idade = 25;
if (idade >= 18) {
System.out.println("Entrada permitida.");
}
}
}Como:
idade = 25;e:
25 >= 18é verdadeiro, o resultado será:
Entrada permitida.
Agora altere:
int idade = 15;A condição:
idade >= 18passará a ser falsa.
Nesse caso, a mensagem não será exibida.
Muitas vezes queremos executar uma ação quando a condição for verdadeira e outra quando for falsa.
Para isso usamos:
if (condicao) {
} else {
}Exemplo:
int idade = 16;
if (idade >= 18) {
System.out.println("Maior de idade");
} else {
System.out.println("Menor de idade");
}Resultado:
Menor de idade
Nesse caso, sempre um dos dois blocos será executado.
Podemos pensar da seguinte forma:
SE condição for verdadeira
execute o primeiro bloco
SENÃO
execute o segundo bloco
Nem sempre temos apenas duas possibilidades.
Imagine uma classificação baseada em nota:
double nota = 7.5;
if (nota >= 9) {
System.out.println("Excelente");
} else if (nota >= 7) {
System.out.println("Aprovado");
} else if (nota >= 5) {
System.out.println("Recuperação");
} else {
System.out.println("Reprovado");
}Como:
nota = 7.5;a primeira condição:
nota >= 9é falsa.
Java passa para:
nota >= 7Essa condição é verdadeira.
Portanto:
Aprovado
será exibido.
Depois disso, Java não continua testando os demais blocos daquela cadeia.
Este é um detalhe muito importante.
Observe:
int idade = 65;
if (idade >= 18) {
System.out.println("Adulto");
} else if (idade >= 60) {
System.out.println("Idoso");
}Qual será o resultado?
Adulto
Mas uma pessoa com 65 anos deveria ser classificada como idosa segundo nossa regra.
O problema está na ordem.
A primeira condição:
idade >= 18já é verdadeira.
Java executa esse bloco e não testa o próximo else if.
Uma solução seria:
int idade = 65;
if (idade >= 60) {
System.out.println("Idoso");
} else if (idade >= 18) {
System.out.println("Adulto");
} else {
System.out.println("Menor de idade");
}Agora o resultado será:
Idoso
Essa situação ensina uma das ideias mais importantes da programação:
Um código pode compilar corretamente e ainda possuir um erro de lógica.
Na lição anterior aprendemos que:
&&representa o operador lógico E.
Imagine que uma pessoa somente possa dirigir se:
- tiver pelo menos 18 anos;
- possuir habilitação.
Podemos escrever:
int idade = 25;
boolean possuiHabilitacao = true;
if (idade >= 18 && possuiHabilitacao) {
System.out.println("Pode dirigir.");
} else {
System.out.println("Não pode dirigir.");
}Para que o primeiro bloco seja executado, as duas condições precisam ser verdadeiras.
Podemos visualizar assim:
idade >= 18 -> true
possuiHabilitacao -> true
true && true -> true
Portanto:
Pode dirigir.
Você poderá encontrar códigos assim:
if (possuiHabilitacao == true) {
System.out.println("Possui habilitação.");
}Isso funciona.
Mas a variável já contém um valor booleano.
Portanto, podemos escrever simplesmente:
if (possuiHabilitacao) {
System.out.println("Possui habilitação.");
}Para verificar o contrário:
if (!possuiHabilitacao) {
System.out.println("Não possui habilitação.");
}O operador:
!significa negação.
Se:
possuiHabilitacao = false;então:
!possuiHabilitacaoserá:
true
O operador:
||representa OU.
Imagine que uma pessoa tenha direito a determinado desconto se for:
- estudante;
- ou tiver 60 anos ou mais.
boolean estudante = false;
int idade = 70;
if (estudante || idade >= 60) {
System.out.println("Possui desconto.");
}Temos:
estudante -> false
idade >= 60 -> true
Portanto:
false || true
resulta em:
true
A mensagem será exibida.
Com ||, basta uma das condições ser verdadeira.
Podemos colocar um if dentro de outro if.
Exemplo:
int idade = 25;
boolean possuiHabilitacao = true;
if (idade >= 18) {
if (possuiHabilitacao) {
System.out.println("Pode dirigir.");
}
}Esse código funciona.
Chamamos isso de condição aninhada.
Porém, nesse exemplo podemos simplificar:
if (idade >= 18 && possuiHabilitacao) {
System.out.println("Pode dirigir.");
}As duas formas são válidas.
Porém, devemos evitar níveis de aninhamento desnecessários porque eles podem tornar o código mais difícil de entender.
Imagine que temos um número representando um dia da semana.
Poderíamos fazer:
int dia = 2;
if (dia == 1) {
System.out.println("Domingo");
} else if (dia == 2) {
System.out.println("Segunda-feira");
} else if (dia == 3) {
System.out.println("Terça-feira");
}Funciona.
Mas Java possui uma estrutura muito útil para situações em que comparamos um mesmo valor contra várias possibilidades:
switchExemplo:
int dia = 2;
switch (dia) {
case 1:
System.out.println("Domingo");
break;
case 2:
System.out.println("Segunda-feira");
break;
case 3:
System.out.println("Terça-feira");
break;
default:
System.out.println("Dia inválido");
}Como:
dia = 2;Java encontrará:
case 2:e exibirá:
Segunda-feira
Cada case representa uma possibilidade.
Por exemplo:
case 1:significa:
Caso o valor do
switchseja 1.
Já:
case 2:significa:
Caso o valor seja 2.
Assim podemos tratar várias alternativas de forma organizada.
Observe:
case 1:
System.out.println("Domingo");
break;O comando:
break;interrompe a execução daquele switch.
Sem ele, no switch tradicional, Java pode continuar executando os próximos casos.
Observe:
int numero = 1;
switch (numero) {
case 1:
System.out.println("Um");
case 2:
System.out.println("Dois");
case 3:
System.out.println("Três");
}O resultado será:
Um
Dois
Três
Isso acontece porque não colocamos break.
Esse comportamento é chamado de:
fall-through.
Em algumas situações ele pode ser intencional.
Porém, muitas vezes representa um erro.
O default funciona de maneira semelhante ao else.
Exemplo:
int dia = 10;
switch (dia) {
case 1:
System.out.println("Domingo");
break;
case 2:
System.out.println("Segunda-feira");
break;
default:
System.out.println("Dia inválido");
}Como nenhum case corresponde ao valor:
10Java executará:
default:Resultado:
Dia inválido
Java também possui uma sintaxe moderna de switch.
Exemplo:
int dia = 2;
switch (dia) {
case 1 -> System.out.println("Domingo");
case 2 -> System.out.println("Segunda-feira");
case 3 -> System.out.println("Terça-feira");
default -> System.out.println("Dia inválido");
}Observe o uso de:
->Nessa forma não precisamos escrever:
break;para impedir que o próximo caso seja executado.
Essa sintaxe deixa muitos switch mais simples e legíveis.
O switch moderno também pode ser usado como uma expressão.
Isso significa que ele pode gerar um valor.
Exemplo:
int dia = 2;
String nomeDia = switch (dia) {
case 1 -> "Domingo";
case 2 -> "Segunda-feira";
case 3 -> "Terça-feira";
default -> "Dia inválido";
};
System.out.println(nomeDia);Resultado:
Segunda-feira
Observe esta parte:
String nomeDia = switch (dia) {O resultado produzido pelo switch será armazenado em:
nomeDiaTambém podemos agrupar valores.
Exemplo:
int dia = 6;
String tipoDia = switch (dia) {
case 1, 7 -> "Fim de semana";
case 2, 3, 4, 5, 6 -> "Dia útil";
default -> "Dia inválido";
};
System.out.println(tipoDia);Resultado:
Dia útil
Aqui:
case 1, 7significa que tanto o valor 1 quanto o valor 7 produzirão:
Fim de semana
Java possui uma forma curta de representar uma decisão simples.
Chamamos de operador ternário.
A estrutura é:
condicao ? valorSeVerdadeiro : valorSeFalsoExemplo:
int idade = 20;
String resultado = idade >= 18
? "Maior de idade"
: "Menor de idade";
System.out.println(resultado);Resultado:
Maior de idade
Podemos ler:
idade é maior ou igual a 18?
SIM -> "Maior de idade"
NÃO -> "Menor de idade"
Este código:
String resultado;
if (idade >= 18) {
resultado = "Maior de idade";
} else {
resultado = "Menor de idade";
}pode ser escrito como:
String resultado = idade >= 18
? "Maior de idade"
: "Menor de idade";As duas versões possuem o mesmo objetivo.
O operador ternário funciona muito bem para decisões pequenas.
Por exemplo:
String status = ativo ? "Ativo" : "Inativo";Isso é simples de entender.
Porém, não devemos transformar toda condição em ternário.
Por exemplo:
String resultado = nota >= 9
? "Excelente"
: nota >= 7
? "Bom"
: nota >= 5
? "Regular"
: "Ruim";Esse código funciona.
Mas fica mais difícil de ler.
Nesse caso, if, else if e else seriam provavelmente uma escolha melhor.
A clareza do código é mais importante do que escrever menos linhas.
Uma regra prática é utilizar if quando trabalhamos com condições como:
idade >= 18nota > 7saldo >= valorCompraou:
idade >= 18 && possuiHabilitacaoOu seja, situações envolvendo:
- comparações;
- intervalos;
- múltiplas condições;
- expressões booleanas.
Já o switch costuma ser interessante quando temos um valor e várias opções bem definidas.
Por exemplo:
1 -> Janeiro
2 -> Fevereiro
3 -> Março
ou:
ADMIN
USUARIO
VISITANTE
Não existe uma regra absoluta.
O objetivo é escolher a estrutura que torne a intenção do código mais clara.
Vamos juntar vários conhecimentos.
public class SistemaAprovacao {
public static void main(String[] args) {
double nota = 7.8;
int faltas = 5;
if (nota >= 7 && faltas <= 10) {
System.out.println("Aluno aprovado.");
} else if (nota >= 5 && faltas <= 10) {
System.out.println("Aluno em recuperação.");
} else {
System.out.println("Aluno reprovado.");
}
}
}Esse pequeno programa utiliza:
double;int;- operadores relacionais;
- operador lógico
&&; if;else if;else.
Começamos, portanto, a combinar diferentes fundamentos da linguagem para representar uma regra de negócio.
Tente resolver os exercícios antes de consultar as soluções.
A prática é fundamental para realmente aprender programação.
Crie uma variável:
int numero = -5;Seu programa deve informar se o número é:
Positivo
Negativo
ou:
Zero
Crie um programa que determine se um número inteiro é par ou ímpar.
Lembre-se do operador:
%Considere:
int a = 15;
int b = 30;Seu programa deve informar:
- se
aé maior; - se
bé maior; - se os números são iguais.
Crie um programa que classifique uma pessoa segundo estas regras:
Menos de 12 anos -> Criança
12 até 17 anos -> Adolescente
18 até 59 anos -> Adulto
60 anos ou mais -> Idoso
Considere:
double numero1 = 10;
double numero2 = 5;
char operacao = '+';Dependendo do valor de:
operacaorealize:
+
-
*
/
Use switch.
Não permita divisão por zero.
Só consulte esta seção depois de tentar resolver os exercícios.
int numero = -5;
if (numero > 0) {
System.out.println("Positivo");
} else if (numero < 0) {
System.out.println("Negativo");
} else {
System.out.println("Zero");
}Observe que o else representa o único caso restante.
Se o número:
- não é maior que zero;
- não é menor que zero;
então ele só pode ser zero.
int numero = 17;
if (numero % 2 == 0) {
System.out.println("Par");
} else {
System.out.println("Ímpar");
}O operador:
%retorna o resto da divisão.
Se:
numero % 2for:
0
o número pode ser dividido por dois sem deixar resto.
Portanto, ele é par.
int a = 15;
int b = 30;
if (a > b) {
System.out.println("A é maior");
} else if (b > a) {
System.out.println("B é maior");
} else {
System.out.println("Os números são iguais");
}Precisamos considerar três possibilidades:
a > b
b > a
a == b
O último caso pode ser representado simplesmente pelo else.
int idade = 35;
if (idade < 12) {
System.out.println("Criança");
} else if (idade < 18) {
System.out.println("Adolescente");
} else if (idade < 60) {
System.out.println("Adulto");
} else {
System.out.println("Idoso");
}Observe que não precisamos escrever:
idade >= 12 && idade < 18Quando Java chega ao segundo teste, já sabemos que:
idade < 12era falso.
Portanto, a pessoa já possui pelo menos 12 anos.
Esse é mais um exemplo de como a ordem das condições influencia nossa lógica.
Uma solução utilizando o switch tradicional:
double numero1 = 10;
double numero2 = 5;
char operacao = '*';
switch (operacao) {
case '+':
System.out.println(numero1 + numero2);
break;
case '-':
System.out.println(numero1 - numero2);
break;
case '*':
System.out.println(numero1 * numero2);
break;
case '/':
if (numero2 != 0) {
System.out.println(numero1 / numero2);
} else {
System.out.println("Não é possível dividir por zero.");
}
break;
default:
System.out.println("Operação inválida.");
}Observe que utilizamos um:
ifdentro de:
case '/'Isso mostra que estruturas de controle podem ser combinadas.
Uma loja fornece descontos segundo estas regras:
Compra abaixo de R$ 100 -> sem desconto
R$ 100 até R$ 499,99 -> 5%
R$ 500 até R$ 999,99 -> 10%
R$ 1.000 ou mais -> 15%
Crie uma variável:
double valorCompra = 750;O programa deverá mostrar:
- valor original;
- percentual de desconto;
- valor do desconto;
- valor final.
Tente resolver antes de continuar.
Uma possível solução é:
double valorCompra = 750;
double percentualDesconto;
if (valorCompra >= 1000) {
percentualDesconto = 0.15;
} else if (valorCompra >= 500) {
percentualDesconto = 0.10;
} else if (valorCompra >= 100) {
percentualDesconto = 0.05;
} else {
percentualDesconto = 0;
}
double valorDesconto = valorCompra * percentualDesconto;
double valorFinal = valorCompra - valorDesconto;
System.out.println("Valor original: " + valorCompra);
System.out.println("Desconto: " + percentualDesconto * 100 + "%");
System.out.println("Valor do desconto: " + valorDesconto);
System.out.println("Valor final: " + valorFinal);Se:
valorCompra = 750;a condição:
valorCompra >= 1000é falsa.
A próxima:
valorCompra >= 500é verdadeira.
Portanto:
percentualDesconto = 0.10;O desconto será de 10%.
Crie um programa com:
int idade = 20;
boolean possuiIngresso = true;
boolean bloqueado = false;Uma pessoa poderá entrar somente se:
- possuir pelo menos 18 anos;
- possuir ingresso;
- não estiver bloqueada.
O resultado deverá ser:
Acesso permitido.
ou:
Acesso negado.
Tente montar uma única expressão utilizando:
&&e:
!Crie:
int mes = 9;Use switch para transformar o número no nome correspondente:
1 -> Janeiro
2 -> Fevereiro
3 -> Março
...
12 -> Dezembro
Para qualquer outro número, mostre:
Mês inválido
Depois tente escrever duas versões:
- usando o
switchtradicional; - usando o
switchmoderno com->.
Esse exercício ajuda a perceber as diferenças entre as duas sintaxes.
Antes de avançar, você deve conseguir explicar com suas próprias palavras:
- para que serve o
if; - quando o bloco de um
ifé executado; - para que serve o
else; - para que serve o
else if; - por que a ordem das condições importa;
- qual é a diferença entre
=e==; - como funciona o operador
&&; - como funciona o operador
||; - como funciona o operador
!; - o que é um
ifaninhado; - quando um
switchpode ser mais adequado que váriosif; - para que serve
case; - para que serve
breaknoswitchtradicional; - o que é fall-through;
- para que serve
default; - como funciona o
switchmoderno com->; - como um
switchpode produzir um valor; - como funciona o operador ternário
? :.
Também deve conseguir entender este programa sem executá-lo:
public class VerificadorAcesso {
public static void main(String[] args) {
int idade = 25;
boolean possuiIngresso = true;
boolean bloqueado = false;
if (idade >= 18 && possuiIngresso && !bloqueado) {
System.out.println("Acesso permitido.");
} else {
System.out.println("Acesso negado.");
}
}
}E deve conseguir prever que, com esses valores, o resultado será:
Acesso permitido.
Mais importante do que decorar a sintaxe é conseguir olhar para uma regra escrita em português e transformá-la em condições Java.
Quando essas estruturas estiverem naturais, estaremos preparados para a Lição 4, na qual aprenderemos laços de repetição com for, while, do-while, além de break e continue.
Veja também: mais conteúdos sobre Java.
Use a Cabeça Java – 3ª Edição: guia do aprendiz para programação no mundo real
Use a Cabeça Java – 3ª Edição: guia do aprendiz para programação no mundo real. Produto recomendado para estudos, programação e produtividade.





Deixe um comentário