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.

Você vai aprender
  • Como escrever um char (aspas simples) e a diferença para uma String.
  • O que é Unicode e por que 'A' + 1 dá 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, true e false, 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"
Tipochar (primitivo)String (objeto)
AspasSimplesDuplas
Quantos caracteresExatamente umZero, 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).

CaracteresCó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ãoResultadoPor quê
'A' + 166Numa 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'65O caminho inverso: mostra o código do caractere.
c++ e c += 2B, DEsses operadores mantêm o tipo char, então o resultado continua sendo letra.
'A' + 'B'131Dois char somados são dois números somados. Para juntar como texto, comece com uma String: "" + 'A' + 'B'.
'7' - '0'7Truque 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étodoPergunta / fazTraduçã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
LinhaO 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).
!pagoO ! ("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.

Dê nomes que soam como perguntas

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

"String cannot be converted to char" (aspas duplas num char)
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";.

"unclosed character literal" (mais de um caractere)
$ 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";.

"empty character literal"
$ 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.

Emoji num 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.

"int cannot be converted to boolean" (0 e 1 não são booleanos)
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;.

"boolean cannot be converted to int" (nem com casting)
$ 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;.

"cannot find symbol … variable True"
$ 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

EscritaO que éExemplo → resultado
'A'Literal charchar c = 'A';
'é'char pelo código Unicode (hexadecimal)é
(int) cCódigo do caractere(int) 'A' → 65
(char) nCaractere do código(char) 66 → B
c - '0'Dígito para número'7' - '0' → 7
"" + c1 + c2Juntar caracteres como texto"" + 'A' + 'B' → AB
Character.isDigit(c)É dígito?true/false
Character.toUpperCase(c)Maiúscula'a' → A
true, falseLiterais booleanboolean 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:

char nota = ;

2. Verdadeiro

Complete com o valor "verdadeiro":

boolean aprovado = ;

3. É dígito?

Complete para perguntar se c é um dígito:

boolean ehNumero = Character.(c);

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

  • char guarda 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.
  • boolean só tem true e false (minúsculos, sem aspas). Quase sempre nasce de uma comparação: idade >= 18.
  • Em Java, boolean não é número: if (5), boolean b = 1 e (int) true não compilam.