Java char e boolean
Faltam dois tipos primitivos para fechar a lista: o char, que guarda um único caractere (uma letra, um dígito, um símbolo), e o boolean, que guarda só verdadeiro ou falso. Eles parecem simples, e são, mas cada um tem uma característica que surpreende quem começa: o char é, por dentro, um número; e o boolean, ao contrário de outras linguagens, não é um número.
- Como escrever um
char(aspas simples) e a diferença para umaString. - O que é Unicode e por que
'A' + 1dá66. - Como transformar número em letra e letra em número com
(char)e(int). - Os métodos úteis de
Character:isDigit,isLetter,toUpperCase… - Como usar
boolean,trueefalse, e os erros de quem tenta usar 0 e 1.
Parte 1: char, um caractere
char vem de character, "caractere": qualquer símbolo que você digita, como A, z, 7, @, ç ou um espaço. Uma variável char guarda exatamente um. O valor vai entre aspas simples:
public class Main {
public static void main(String[] args) {
char turma = 'B';
char simbolo = '@';
char digito = '7';
char acento = 'ç';
char unicode = 'é';
char espaco = ' ';
System.out.println(turma);
System.out.println(simbolo);
System.out.println(digito);
System.out.println(acento);
System.out.println(unicode);
System.out.println("[" + espaco + "]");
}
}
$ javac Main.java && java Main B @ 7 ç é « 'é' é o código Unicode do é [ ] « o espaço também é um caractere
- char
- O tipo: um caractere.
- turma
- O nome da variável.
- 'B'
- O valor, entre aspas simples. Dentro delas cabe um caractere só.
Repare em char digito = '7';: é o símbolo 7, como aparece num teclado ou numa placa de carro, e não o número sete. Você vai ver daqui a pouco que '7' e 7 são coisas bem diferentes.
'A' × "A"
'A' | "A" | |
|---|---|---|
| Tipo | char (primitivo) | String (objeto) |
| Aspas | Simples | Duplas |
| Quantos caracteres | Exatamente um | Zero, um ou muitos ("", "Ana") |
| Tem métodos? | Não (use Character.xxx(c)) | Sim ("Ana".length()) |
Trocar as aspas é o erro mais comum com char; veja os erros reais em Quando dá errado.
Unicode: cada caractere tem um número
O computador só guarda números. Para guardar letras, existe uma tabela gigante que dá um número a cada caractere de todos os idiomas: o Unicode. Nela, A é 65, B é 66, a é 97, é é 233. O char guarda, na verdade, esse número (de 0 a 65.535, em 16 bits), e o Java o mostra como letra.
Você pode escrever qualquer caractere pelo código, no formato '\uXXXX', com o número em hexadecimal (é = 233 = é). Isso é útil para símbolos que não estão no teclado, como '°' (o ° de graus).
| Caracteres | Códigos |
|---|---|
'0' a '9' | 48 a 57 |
'A' a 'Z' | 65 a 90 |
'a' a 'z' | 97 a 122 |
' ' (espaço) | 32 |
As letras estão em sequência na tabela. É isso que permite "fazer contas" com letras.
Contas com char: 'A' + 1
public class Main {
public static void main(String[] args) {
System.out.println('A' + 1);
System.out.println((char) ('A' + 1));
System.out.println((int) 'A');
System.out.println((int) 'a');
System.out.println((char) 97);
char c = 'A';
c++;
System.out.println(c);
c += 2;
System.out.println(c);
System.out.println('A' + 'B');
System.out.println("" + 'A' + 'B');
System.out.println('7' - '0');
System.out.println('a' < 'b');
}
}
$ javac Main.java && java Main 66 « 'A' + 1: a conta usou o código do A (65) B « (char) transforma o 66 de volta em letra 65 97 a B « c++ avançou para a próxima letra D « c += 2 avançou mais duas 131 « 'A' + 'B' = 65 + 66, não "AB"! AB « começando com "", vira texto 7 « '7' - '0' = 55 - 48 true « 'a' vem antes de 'b' na tabela
| Expressão | Resultado | Por quê |
|---|---|---|
'A' + 1 | 66 | Numa conta, o char vira o seu código (int). 65 + 1 = 66, e o resultado é int. |
(char) ('A' + 1) | B | (char) é um casting: "trate este número como caractere". Os parênteses em volta da conta são necessários. |
(int) 'A' | 65 | O caminho inverso: mostra o código do caractere. |
c++ e c += 2 | B, D | Esses operadores mantêm o tipo char, então o resultado continua sendo letra. |
'A' + 'B' | 131 | Dois char somados são dois números somados. Para juntar como texto, comece com uma String: "" + 'A' + 'B'. |
'7' - '0' | 7 | Truque clássico para transformar o dígito '7' no número 7: os dígitos estão em sequência a partir do '0' (48). |
Casting e as regras de qual tipo resulta de cada conta estão em Conversão de Tipos. Os operadores ++ e += estão em Operadores Aritméticos e Operadores de Atribuição.
Missão: o programa deveria mostrar a letra que vem depois de J, mas mostra 75. Use um casting (char) para que ele mostre K.
public class Main {
public static void main(String[] args) {
char letra = 'J';
System.out.println(letra + 1);
}
}
public class Main {
public static void main(String[] args) {
char letra = 'J';
System.out.println((char) (letra + 1));
}
}
A classe Character: perguntas sobre um caractere
Como char é primitivo, ele não tem métodos. Mas a classe Character (o wrapper do char) tem vários métodos que recebem um caractere entre parênteses e respondem perguntas sobre ele:
public class Main {
public static void main(String[] args) {
char c = '7';
System.out.println(Character.isDigit(c));
System.out.println(Character.isLetter(c));
System.out.println(Character.isLetter('ç'));
System.out.println(Character.isUpperCase('A'));
System.out.println(Character.isLowerCase('A'));
System.out.println(Character.isWhitespace(' '));
System.out.println(Character.isLetterOrDigit('#'));
System.out.println(Character.toUpperCase('a'));
System.out.println(Character.toLowerCase('Ç'));
System.out.println(Character.getNumericValue('7'));
}
}
$ javac Main.java && java Main true « '7' é dígito false « '7' não é letra true « ç é letra (o Java conhece todos os idiomas) true false true false « # não é letra nem dígito A ç 7 « o número 7, a partir do caractere '7'
| Método | Pergunta / faz | Tradução do nome |
|---|---|---|
Character.isDigit(c) | É um dígito de 0 a 9? | is digit = "é dígito" |
Character.isLetter(c) | É uma letra (de qualquer idioma)? | "é letra" |
Character.isLetterOrDigit(c) | É letra ou dígito? | "é letra ou dígito" |
Character.isUpperCase(c) / isLowerCase(c) | É maiúscula? / minúscula? | upper case = "caixa alta" |
Character.isWhitespace(c) | É espaço, tab ou quebra de linha? | "é espaço em branco" |
Character.toUpperCase(c) / toLowerCase(c) | Devolve a versão maiúscula / minúscula | "para maiúscula" |
Character.getNumericValue(c) | Devolve o valor numérico do dígito ('7' → 7) | "obter valor numérico" |
Os métodos is… respondem true ou false, que são exatamente os valores do próximo tipo. Eles brilham quando você percorre um texto letra por letra (validar uma senha, contar vogais), assunto de Métodos de String e for.
Parte 2: boolean, verdadeiro ou falso
Um interruptor só tem duas posições: ligado ou desligado. O boolean é a mesma coisa: só existem dois valores, true (verdadeiro) e false (falso). São palavras reservadas do Java, escritas sem aspas e em minúsculas. O nome homenageia George Boole, matemático que criou a "álgebra" do verdadeiro e falso.
public class Main {
public static void main(String[] args) {
boolean ligado = true;
boolean pago = false;
int idade = 17;
boolean maiorDeIdade = idade >= 18;
System.out.println(ligado);
System.out.println(pago);
System.out.println(maiorDeIdade);
System.out.println("Pode dirigir? " + maiorDeIdade);
pago = true;
System.out.println(!pago);
}
}
$ javac Main.java && java Main true false false « 17 >= 18 é falso Pode dirigir? false false « !pago: o contrário de true
| Linha | O que faz |
|---|---|
boolean ligado = true; | Guarda o valor verdadeiro. |
boolean maiorDeIdade = idade >= 18; | Guarda o resultado de uma pergunta: "idade é maior ou igual a 18?". Toda comparação dá um boolean (Operadores de Comparação). |
!pago | O ! ("não") inverte: !true é false (Operadores Lógicos). |
Raramente você escreve true ou false diretamente. Quase sempre, o boolean nasce de uma comparação e é usado para decidir o que o programa faz, num if ou num while. Isso é o assunto de Expressões Booleanas.
Variáveis boolean ficam mais legíveis com nomes de sim/não: pago, maiorDeIdade, temEstoque, estaAtivo, podeEntrar. Assim, if (temEstoque) se lê como uma frase.
boolean não é 0 nem 1
Em C, JavaScript e Python, 0 vale "falso" e qualquer outro número vale "verdadeiro". Em Java, não: boolean e números são tipos completamente separados, e o Java não converte um no outro de jeito nenhum, nem com casting. Os erros reais estão logo abaixo, em Quando dá errado. Parece rígido, mas evita uma classe inteira de erros, como o famoso if (x = 5) que em C compila e faz a coisa errada.
Missão: a loja da Ana dá frete grátis em compras a partir de 100 reais. Crie a variável boolean freteGratis com o resultado da comparação total >= 100 e mostre Frete grátis? true.
public class Main {
public static void main(String[] args) {
double total = 135.50;
// crie a variável freteGratis aqui
System.out.println("Frete grátis? " + freteGratis);
}
}
public class Main {
public static void main(String[] args) {
double total = 135.50;
boolean freteGratis = total >= 100;
System.out.println("Frete grátis? " + freteGratis);
}
}
Quando dá errado
public class Main {
public static void main(String[] args) {
char letra = "A";
}
}
$ javac Main.java
Main.java:3: error: incompatible types: String cannot be converted to char
char letra = "A";
^
1 error
O que quer dizer: "A", com aspas duplas, é uma String de uma letra, não um char.
Como consertar: aspas simples: char letra = 'A';. Ou, se você queria texto, String letra = "A";.
$ javac Main.java
Main.java:3: error: unclosed character literal
char letras = 'AB';
^
Main.java:3: error: unclosed character literal
char letras = 'AB';
^
Main.java:3: error: not a statement
char letras = 'AB';
^
3 errors
O que quer dizer: "literal de caractere não fechado". Depois de 'A o Java esperava a aspa de fechamento e encontrou um B; daí em diante se perdeu e gerou mais dois erros. Quando o javac mostra vários erros na mesma linha, corrija o primeiro: os outros costumam ser consequência.
Como consertar: um caractere só por char; mais de um é String: String letras = "AB";.
$ javac Main.java
Main.java:3: error: empty character literal
char vazio = '';
^
1 error
O que quer dizer: não existe char vazio; ele sempre tem exatamente um caractere. (Uma String pode ser vazia: "".)
Como consertar: use um espaço (' ') se a ideia era "em branco", ou uma String.
char: "character literal contains more than one UTF-16 code unit"
O que quer dizer: a maioria dos emojis tem código acima de 65.535 e não cabe em 16 bits; o Java os representa com dois char. Por isso char com um emoji não compila.
Como consertar: guarde emojis em String.
public class Main {
public static void main(String[] args) {
int estoque = 5;
if (estoque) {
System.out.println("Tem estoque");
}
}
}
$ javac Main.java
Main.java:4: error: incompatible types: int cannot be converted to boolean
if (estoque) {
^
1 error
O que quer dizer: o if exige uma condição boolean, e estoque é um int. Em outras linguagens, "5" valeria "verdadeiro"; em Java, não. O mesmo erro aparece em boolean ativo = 1;.
Como consertar: escreva a pergunta completa: if (estoque > 0). Para guardar: boolean ativo = true;.
$ javac Main.java
Main.java:4: error: incompatible types: boolean cannot be converted to int
int x = (int) ativo;
^
1 error
O que quer dizer: nem o casting converte boolean em número.
Como consertar: se você precisa de 1 ou 0, decida com o operador ternário: int x = ativo ? 1 : 0;.
$ javac Main.java
Main.java:3: error: cannot find symbol
boolean ativo = True;
^
symbol: variable True
location: class Main
1 error
O que quer dizer: com maiúscula, True não é o valor verdadeiro; o Java procura uma variável com esse nome. (Quem vem do Python cai muito nessa.)
Como consertar: true e false, sempre minúsculos. E sem aspas: boolean ativo = "true"; dá String cannot be converted to boolean.
Missão: no JShell, descubra o código Unicode do ç. Digite (int) 'ç'. Depois experimente o caminho contrário, (char) 231.
(int) 'ç'
Referência
| Escrita | O que é | Exemplo → resultado |
|---|---|---|
'A' | Literal char | char c = 'A'; |
'é' | char pelo código Unicode (hexadecimal) | é |
(int) c | Código do caractere | (int) 'A' → 65 |
(char) n | Caractere do código | (char) 66 → B |
c - '0' | Dígito para número | '7' - '0' → 7 |
"" + c1 + c2 | Juntar caracteres como texto | "" + 'A' + 'B' → AB |
Character.isDigit(c) | É dígito? | true/false |
Character.toUpperCase(c) | Maiúscula | 'a' → A |
true, false | Literais boolean | boolean pago = true; |
boolean b = x > 0; | Guardar o resultado de uma comparação | |
!b | "Não": inverte | !true → false |
Exercícios
1. As aspas do char
Complete para guardar a letra C na variável:
2. Verdadeiro
Complete com o valor "verdadeiro":
3. É dígito?
Complete para perguntar se c é um dígito:
4. O que System.out.println('A' + 'B'); mostra?
5. O que acontece com boolean ativo = 1;?
6. Qual o resultado de '9' - '0'?
Resumo
charguarda um caractere, entre aspas simples:'A'. Texto, com aspas duplas, éString.- Por dentro, o
charé o código Unicode do caractere ('A'= 65). Em contas ele vira número:'A' + 1=66;(char) 66=B. Character.isDigit,isLetter,isUpperCase,toUpperCase… respondem perguntas sobre um caractere.booleansó temtrueefalse(minúsculos, sem aspas). Quase sempre nasce de uma comparação:idade >= 18.- Em Java,
booleannão é número:if (5),boolean b = 1e(int) truenão compilam.