Java Expressões Booleanas
Todo programa toma decisões: "a aluna foi aprovada?", "a senha está certa?", "é fim de semana?". Antes de decidir, o programa precisa perguntar, e a resposta é sempre true (verdadeiro) ou false (falso). Uma pergunta assim, escrita em Java, se chama expressão booleana. Esta aula abre a seção "Decisões": tudo o que vem depois (if, ternário, switch) depende dela.
- O que é uma expressão booleana e onde ela aparece.
- Como guardar a resposta numa variável
booleancom um nome que se lê como uma pergunta. - Como combinar perguntas com
&&(e),||(ou) e!(não), incluindo faixas como "entre 0 e 10". - Como a ordem das perguntas evita uma
NullPointerException(curto-circuito). - Como transformar o texto
"true"embooleancomBoolean.parseBoolean. - Os erros que o
javacmostra quando a expressão não é booleana.
A ideia: perguntas de sim ou não
Pense num formulário com caixinhas de marcar: "Maior de 18 anos? ☐", "Possui carteira de motorista? ☐". Cada caixinha só tem dois estados: marcada ou não. Em Java, cada caixinha é um valor boolean, e a pergunta que decide se ela fica marcada é uma expressão booleana.
O nome vem de George Boole, matemático inglês do século XIX que criou a "álgebra" do verdadeiro e falso. Você conheceu o tipo boolean em char e boolean, e os operadores que fazem as perguntas em Operadores de Comparação e Operadores Lógicos. Aqui vamos juntar tudo para escrever perguntas reais.
Perguntas que viram true ou false
Qualquer comparação é uma expressão booleana. O Java calcula a resposta, e você pode guardá-la numa variável boolean:
public class Main {
public static void main(String[] args) {
int idade = 17;
double nota = 8.5;
String cidade = "Recife";
boolean maiorDeIdade = idade >= 18;
boolean aprovada = nota >= 7.0;
boolean ehRecife = cidade.equals("Recife");
System.out.println(maiorDeIdade);
System.out.println(aprovada);
System.out.println(ehRecife);
System.out.println(idade == 17);
System.out.println(10 > 3);
}
}
$ java Main.java false « 17 >= 18? não true « 8.5 >= 7.0? sim true « a cidade é "Recife"? sim true « a pergunta pode ir direto no println true
- boolean maiorDeIdade
- Uma variável que guarda
trueoufalse. - =
- Atribuição: "guarde aqui o resultado da pergunta".
- idade >= 18
- A pergunta (a expressão booleana): "a idade é maior ou igual a 18?". O Java a calcula na hora, com o valor que
idadetem naquele momento. - cidade.equals("Recife")
- Métodos também podem ser perguntas. Todo método que devolve
boolean(equals,isEmpty,contains,startsWith…) serve como expressão booleana. Lembre que Strings se comparam comequals, não com==(veja Strings).
| Tipo de pergunta | Exemplo |
|---|---|
| Comparação de números | idade >= 18, nota == 10, saldo < 0, x != 0 |
| Comparação de textos | nome.equals("Ana"), resposta.equalsIgnoreCase("sim") |
Método que devolve boolean | texto.isBlank(), email.contains("@"), Character.isDigit(c) |
Uma variável boolean | aprovada |
| Os valores literais | true, false |
| Combinações | idade >= 18 && temCarteira |
Dê nomes que se leem como perguntas
Uma variável boolean bem nomeada torna o código quase uma frase em português. Bons padrões: ehMaior, estaAprovada, temDesconto, podeVotar, fimDeSemana. Em inglês, o costume é isActive, hasDiscount, canVote. Evite nomes vagos como flag, teste ou b: daqui a um mês, ninguém vai saber o que true quer dizer ali.
Combinar perguntas: &&, || e !
Perguntas da vida real raramente são simples. "Pode dirigir?" depende da idade e da carteira. "É fim de semana?" é sábado ou domingo. Os operadores lógicos juntam perguntas:
| Operador | Lê-se | É true quando… |
|---|---|---|
a && b | "a e b" | as duas são verdadeiras |
a || b | "a ou b" | pelo menos uma é verdadeira |
!a | "não a" | a é falsa (inverte) |
public class Main {
public static void main(String[] args) {
int idade = 20;
boolean temCarteira = false;
boolean podeDirigir = idade >= 18 && temCarteira;
System.out.println("Pode dirigir? " + podeDirigir);
String dia = "sábado";
boolean fimDeSemana = dia.equals("sábado") || dia.equals("domingo");
System.out.println("Fim de semana? " + fimDeSemana);
double nota = 11.0;
boolean notaValida = nota >= 0 && nota <= 10;
System.out.println("Nota válida? " + notaValida);
boolean chovendo = true;
boolean levaGuardaChuva = chovendo;
boolean vaiAPraia = !chovendo;
System.out.println(levaGuardaChuva + " " + vaiAPraia);
}
}
$ java Main.java Pode dirigir? false « tem idade, mas não tem carteira: o && exige as duas Fim de semana? true « é sábado: basta uma para o || dar true Nota válida? false « 11 passa de 10 true false « ! inverte: chovendo → não vai à praia
Faixas: "entre 0 e 10"
Na matemática escrevemos 0 ≤ nota ≤ 10. Em Java, isso não funciona (veja "Quando dá errado"): é preciso fazer duas perguntas e juntar com &&: nota >= 0 && nota <= 10. Leia em voz alta: "nota maior ou igual a zero e nota menor ou igual a dez".
O contrário, "fora da faixa", usa ||: nota < 0 || nota > 10 ("menor que zero ou maior que dez"). Uma nota não pode ser as duas coisas ao mesmo tempo, então nota < 0 && nota > 10 seria sempre false, um erro de lógica comum.
Inverter uma combinação
Quando você coloca um ! na frente de uma combinação, o && vira || e vice-versa (as "leis de De Morgan"):
public class Main {
public static void main(String[] args) {
boolean a = true;
boolean b = false;
System.out.println(!(a && b));
System.out.println(!a || !b);
System.out.println(!(a || b));
System.out.println(!a && !b);
System.out.println(a ^ b);
System.out.println(a != b);
System.out.println(a == b);
}
}
$ java Main.java true « !(a && b) … true « … é o mesmo que !a || !b false « !(a || b) … false « … é o mesmo que !a && !b true « ^ (ou exclusivo): true quando são DIFERENTES true « != entre booleanos faz o mesmo que ^ false
Exemplo do dia a dia: "não é (sábado ou domingo)" é o mesmo que "não é sábado e não é domingo", ou seja, dia útil. O ^ (ou exclusivo, "um ou outro, mas não os dois") é raro; a != b diz a mesma coisa de um jeito mais claro.
Missão: no cinema, tem meia-entrada quem tem menos de 18 anos, ou 60 ou mais, ou é estudante. Complete a expressão de meia usando ||. Com idade = 65, a saída deve ser Meia-entrada: true. Depois teste com outras idades.
public class Main {
public static void main(String[] args) {
int idade = 65;
boolean estudante = false;
boolean meia = false; // troque false pela expressão
System.out.println("Meia-entrada: " + meia);
}
}
public class Main {
public static void main(String[] args) {
int idade = 65;
boolean estudante = false;
boolean meia = idade < 18 || idade >= 60 || estudante;
System.out.println("Meia-entrada: " + meia);
}
}
A ordem importa: curto-circuito
O && e o || são "preguiçosos": avaliam da esquerda para a direita e param assim que a resposta está decidida. Num &&, se a primeira pergunta é false, o resultado já é false, e a segunda nem é feita. Num ||, se a primeira é true, pronto. Isso se chama avaliação em curto-circuito, e é uma proteção valiosa:
public class Main {
public static void main(String[] args) {
String nome = null;
boolean temNome = nome != null && nome.length() > 0;
System.out.println(temNome);
boolean quebra = nome.length() > 0 && nome != null;
System.out.println(quebra);
}
}
$ java Main.java false Exception in thread "main" java.lang.NullPointerException: Cannot invoke "String.length()" because "<local1>" is null at Main.main(Main.java:6)
As duas linhas fazem as mesmas perguntas, em ordem diferente:
- Linha 4:
nome != nulléfalse, e o&¶ ali. Onome.length()nunca roda. Resultado:false, sem erro. - Linha 6:
nome.length()roda primeiro, comnomevalendonull, e derruba o programa (aNullPointerExceptionque você conheceu em Strings).
Regra: coloque primeiro a pergunta que protege ("existe?", "não é zero?") e depois a que depende dela. Outro exemplo clássico: divisor != 0 && total / divisor > 5.
Validar com várias perguntas
Quando a condição fica grande, quebre em variáveis com nomes claros, e junte no fim. Fica muito mais fácil de ler e de achar erros:
public class Main {
public static void main(String[] args) {
String email = "ana@exemplo.com";
String senha = "java2026";
boolean emailOk = email.contains("@") && email.endsWith(".com");
boolean senhaLonga = senha.length() >= 8;
boolean temDigito = Character.isDigit(senha.charAt(senha.length() - 1));
boolean cadastroOk = emailOk && senhaLonga && temDigito;
System.out.println("E-mail ok: " + emailOk);
System.out.println("Senha longa: " + senhaLonga);
System.out.println("Termina com dígito: " + temDigito);
System.out.println("Cadastro ok: " + cadastroOk);
}
}
$ java Main.java E-mail ok: true Senha longa: true Termina com dígito: true Cadastro ok: true
Character.isDigit(c) pergunta "este caractere é um dígito?" (veja char e boolean); senha.charAt(senha.length() - 1) é o último caractere (veja Métodos de String). Compare com a versão "tudo numa linha só": email.contains("@") && email.endsWith(".com") && senha.length() >= 8 && Character.isDigit(senha.charAt(senha.length() - 1)). Funciona, mas qual parte falhou quando dá false?
Usar um boolean numa decisão
O lugar natural de uma expressão booleana é a condição de um if (assunto da próxima aula). Um detalhe de estilo: como a variável já é true ou false, não precisa compará-la com true:
public class Main {
public static void main(String[] args) {
boolean aprovado = true;
if (aprovado == true) {
System.out.println("Parabéns!");
}
if (aprovado) {
System.out.println("Parabéns de novo!");
}
if (!aprovado) {
System.out.println("Não aparece");
}
}
}
$ java Main.java Parabéns! Parabéns de novo!
if (aprovado == true) e if (aprovado) fazem o mesmo, mas a segunda se lê como português: "se aprovado". Para o contrário, if (!aprovado): "se não aprovado", em vez de aprovado == false.
Texto para boolean: Boolean.parseBoolean
Às vezes a resposta chega como texto: de um arquivo de configuração, de um argumento da linha de comando, do teclado. Boolean.parseBoolean(texto) ("analisar como booleano") transforma em boolean:
public class Main {
public static void main(String[] args) {
System.out.println(Boolean.parseBoolean("true"));
System.out.println(Boolean.parseBoolean("TRUE"));
System.out.println(Boolean.parseBoolean("True"));
System.out.println(Boolean.parseBoolean("sim"));
System.out.println(Boolean.parseBoolean("yes"));
System.out.println(Boolean.parseBoolean(" true"));
System.out.println(Boolean.parseBoolean(null));
boolean ativo = true;
String texto = String.valueOf(ativo);
System.out.println(texto + " tem " + texto.length() + " letras");
System.out.println(Boolean.TRUE + " " + Boolean.FALSE);
}
}
$ java Main.java true « "true" true « maiúsculas não importam true false « "sim" não é reconhecido false « nem "yes" false « nem com espaço na frente false « null também dá false, sem erro true tem 4 letras « o caminho contrário: boolean para texto true false
A regra é simples e rígida: só o texto true (em qualquer combinação de maiúsculas) vira true; todo o resto vira false, sem erro nenhum. Isso é perigoso: um "ture" digitado errado vira false calado. Se o texto vem de uma pessoa, limpe-o antes (texto.strip()) e, se quiser aceitar "sim", compare você mesmo: resposta.strip().equalsIgnoreCase("sim").
Boolean, com B maiúsculo, é a classe "embrulho" (wrapper) do tipo boolean; ela guarda esses métodos de ajuda. Você vai ver os wrappers em detalhe em Wrappers e Autoboxing.
Brinque no JShell: teste Boolean.parseBoolean("TRUE"), Boolean.parseBoolean("sim"), e crie int idade = 30 para perguntar idade >= 18 && idade < 65. O JShell real responde assim:
$ jshell
| Welcome to JShell -- Version 25.0.4.1
| For an introduction type: /help intro
jshell> Boolean.parseBoolean("TRUE")
$1 ==> true
jshell> Boolean.parseBoolean("sim")
$2 ==> false
jshell> int idade = 30
idade ==> 30
jshell> idade >= 18 && idade < 65
$4 ==> true
jshell> /exit
| Goodbye
Quando dá errado
error: incompatible types: int cannot be converted to boolean
Este código tem um erro de propósito.
public class Main {
public static void main(String[] args) {
boolean ligado = 1;
System.out.println(ligado);
}
}
$ javac Main.java
Main.java:3: error: incompatible types: int cannot be converted to boolean
boolean ligado = 1;
^
1 error
O que aconteceu: em algumas linguagens (C, Python, JavaScript), 1 vale como verdadeiro e 0 como falso. Em Java, não: boolean só aceita true e false.
Como resolver: boolean ligado = true;. Se você tem um número, faça a pergunta: boolean ligado = codigo == 1;.
error: incompatible types: String cannot be converted to boolean
Este código tem um erro de propósito.
public class Main {
public static void main(String[] args) {
boolean ativo = "true";
System.out.println(ativo);
}
}
$ javac Main.java
Main.java:3: error: incompatible types: String cannot be converted to boolean
boolean ativo = "true";
^
1 error
O que aconteceu: com aspas, "true" é um texto, não o valor true.
Como resolver: tire as aspas (true) ou, se o texto vem de fora, Boolean.parseBoolean("true").
error: bad operand types for binary operator '<='
Este código tem um erro de propósito.
public class Main {
public static void main(String[] args) {
int nota = 5;
boolean entre = 0 <= nota <= 10;
System.out.println(entre);
}
}
$ javac Main.java
Main.java:4: error: bad operand types for binary operator '<='
boolean entre = 0 <= nota <= 10;
^
first type: boolean
second type: int
1 error
O que aconteceu: o Java faz uma comparação por vez, da esquerda para a direita. 0 <= nota virou true; depois tentou true <= 10, comparando um boolean (first type) com um int (second type), o que não existe.
Como resolver: duas perguntas ligadas por &&: nota >= 0 && nota <= 10.
error: illegal start of type (pergunta pela metade)
Este código tem um erro de propósito.
public class Main {
public static void main(String[] args) {
int idade = 20;
boolean ok = idade > 18 & < 65;
System.out.println(ok);
}
}
$ javac Main.java
Main.java:4: error: illegal start of type
boolean ok = idade > 18 & < 65;
^
1 error
O que aconteceu: em português dizemos "idade maior que 18 e menor que 65", sem repetir "idade". Em Java, cada lado do operador precisa de uma pergunta completa. O javac encontrou < onde esperava um valor. (Repare também que foi usado &, um só, em vez de &&; o & sozinho existe, mas não faz curto-circuito.)
Como resolver: idade > 18 && idade < 65.
error: ';' expected com and ou or
Este código tem um erro de propósito.
public class Main {
public static void main(String[] args) {
int idade = 20;
boolean adulto = idade >= 18 and idade < 65;
System.out.println(adulto);
}
}
$ javac Main.java
Main.java:4: error: ';' expected
boolean adulto = idade >= 18 and idade < 65;
^
Main.java:4: error: ';' expected
boolean adulto = idade >= 18 and idade < 65;
^
Main.java:4: error: illegal start of type
boolean adulto = idade >= 18 and idade < 65;
^
3 errors
O que aconteceu: and, or e not são palavras do Python, não do Java. O javac achou que a linha terminava em 18 e pediu um ;.
Como resolver: &&, || e !.
NullPointerException numa condição com &&
O que aconteceu: a pergunta que usa o objeto veio antes da que verifica se ele existe: nome.length() > 0 && nome != null.
Como resolver: inverta a ordem: nome != null && nome.length() > 0.
Referência
| Escrita | Significado | Exemplo |
|---|---|---|
boolean b = expr; | Guarda a resposta | boolean maior = idade >= 18; |
a && b | E (curto-circuito) | idade >= 18 && temCarteira |
a || b | Ou (curto-circuito) | dia.equals("sábado") || dia.equals("domingo") |
!a | Não | !chovendo |
x >= min && x <= max | Dentro da faixa | nota >= 0 && nota <= 10 |
x < min || x > max | Fora da faixa | nota < 0 || nota > 10 |
!(a && b) = !a || !b | De Morgan | |
a != b (ou a ^ b) | Ou exclusivo | |
Boolean.parseBoolean(s) | Texto → boolean (só "true" dá true) | Boolean.parseBoolean("TRUE") → true |
String.valueOf(b) | boolean → texto | String.valueOf(false) → "false" |
Exercícios
Missão final: uma senha é válida se tem pelo menos 8 caracteres, não contém espaço e não é igual ao usuário. Crie as três variáveis boolean e a variável valida, que junta as três. Mostre as quatro, no formato abaixo. Com a senha "ana 2026", a saída é:Tamanho ok: trueSem espaço: falseDiferente do usuário: trueSenha válida: false
public class Main {
public static void main(String[] args) {
String usuario = "ana";
String senha = "ana 2026";
// crie tamanhoOk, semEspaco, diferente e valida
}
}
public class Main {
public static void main(String[] args) {
String usuario = "ana";
String senha = "ana 2026";
boolean tamanhoOk = senha.length() >= 8;
boolean semEspaco = !senha.contains(" ");
boolean diferente = !senha.equals(usuario);
boolean valida = tamanhoOk && semEspaco && diferente;
System.out.println("Tamanho ok: " + tamanhoOk);
System.out.println("Sem espaço: " + semEspaco);
System.out.println("Diferente do usuário: " + diferente);
System.out.println("Senha válida: " + valida);
}
}
1. Faixa
Complete para saber se temperatura está entre 20 e 30 (incluindo os dois):
2. Inverter
Complete para que diaUtil seja o contrário de fimDeSemana:
3. Texto para boolean
Quanto vale Boolean.parseBoolean("verdadeiro")?
4. Com int x = 15;, quanto vale x > 10 && x < 12 || x == 15?
5. Qual expressão não lança exceção quando texto é null?
6. Qual expressão é sempre false, para qualquer nota?
Resumo
- Uma expressão booleana é uma pergunta cuja resposta é
trueoufalse: comparações, métodos comoequalseisEmpty, variáveisboolean. - Dê às variáveis
booleannomes que se leem como perguntas:podeVotar,temDesconto. &&exige as duas;||basta uma;!inverte. Faixa:x >= min && x <= max(nuncamin <= x <= max).&&e||param assim que sabem a resposta (curto-circuito): ponha primeiro a pergunta que protege, comonome != null.- Use
if (aprovado)eif (!aprovado), sem== true. Boolean.parseBooleansó reconhece"true"(qualquer caixa); todo o resto virafalse.