Java Caracteres Especiais
Como colocar uma aspa dupla dentro de um texto, se a aspa dupla é justamente o que marca onde o texto termina? E como escrever uma quebra de linha, um tab ou uma letra que não existe no seu teclado? A resposta é a barra invertida \, que avisa ao Java: "o próximo caractere é especial".
- O que é uma sequência de escape e por que ela existe.
\"(aspa dupla),\\(barra invertida),\'(aspa simples).\n(quebra de linha) e\t(tab), para organizar a saída.- Os escapes Unicode, como
\u00e9(é), e a pegadinha deles em comentários. - Os erros reais:
illegal escape character,illegal unicode escape,unclosed string literaleempty character literal.
O problema: a aspa que fecha cedo demais
A Ana quer mostrar a frase Ela disse "oi" e foi embora.. A primeira tentativa:
Este código tem um erro de propósito.
public class Main {
public static void main(String[] args) {
System.out.println("Ela disse "oi" e foi embora.");
}
}
$ javac Main.java
Main.java:3: error: ')' or ',' expected
System.out.println("Ela disse "oi" e foi embora.");
^
Main.java:3: error: ';' expected
System.out.println("Ela disse "oi" e foi embora.");
^
2 errors
Para o javac, o texto acabou na segunda aspa: "Ela disse ". Depois veio oi, que ele não sabe o que é, e outro texto " e foi embora.". O ^ aponta exatamente onde a confusão começou.
A saída é avisar ao Java que aquela aspa é parte do texto, e não o fim dele. É isso que a barra invertida faz.
A barra invertida: sequências de escape
Dentro de um texto entre aspas, a barra invertida \ (backslash) junta-se ao caractere seguinte e os dois formam um único caractere especial. O par se chama sequência de escape: a barra "escapa" do significado normal do caractere. É como o "entre aspas" que fazemos com os dedos ao falar: muda o sentido do que vem a seguir.
public class Main {
public static void main(String[] args) {
System.out.println("Ela disse \"oi\" e foi embora.");
System.out.println("Pasta: C:\\Users\\Ana");
System.out.println("Linha 1\nLinha 2\nLinha 3");
System.out.println("Nome\tNota");
System.out.println("Ana\t9.5");
System.out.println("Bruno\t7.0");
System.out.println("copo d'água");
System.out.println("copo d\'água");
char aspa = '\'';
System.out.println(aspa);
System.out.println("a\nb".length());
}
}
$ java Main.java Ela disse "oi" e foi embora. Pasta: C:\Users\Ana Linha 1 Linha 2 Linha 3 Nome Nota Ana 9.5 Bruno 7.0 copo d'água copo d'água ' 3
Vamos um por um.
\": aspa dupla dentro do texto
\" vira uma aspa dupla comum, que não fecha o texto. Em "Ela disse \"oi\" e foi embora.", as únicas aspas "de verdade" são a primeira e a última.
\\: a própria barra
Se a barra é o "sinal de escape", como escrever uma barra de verdade (num caminho do Windows, por exemplo)? Escapando a própria barra: \\ vira uma barra. Por isso "C:\\Users\\Ana" mostra C:\Users\Ana.
\n: quebra de linha
\n (de new line, "nova linha") pula para a linha de baixo no meio do texto. Um único println mostrou três linhas. Repare na última linha da saída: "a\nb".length() é 3. A sequência \n ocupa duas teclas no código, mas é um caractere só dentro da String (o caractere "quebra de linha").
\t: tab
\t (de tab, tabulação) avança até a próxima "coluna" do terminal, como a tecla Tab num editor de texto. Serve para alinhar colunas, como a tabela de notas acima: os nomes têm tamanhos diferentes, mas as notas ficaram alinhadas.
\': aspa simples
Dentro de uma String (aspas duplas), a aspa simples é um caractere comum: "copo d'água" funciona sem barra, e "copo d\'água" também (a barra é aceita, mas desnecessária). Já num char, que é delimitado por aspas simples, a barra é obrigatória: '\''.
| Você quer | Dentro de "…" (String) | Dentro de '…' (char) |
|---|---|---|
| Aspa dupla | \" (obrigatório) | '"' ou '\"' |
| Aspa simples | ' ou \' | '\'' (obrigatório) |
| Barra invertida | \\ | '\\' |
Missão: mostre exatamente estas duas linhas, com as aspas e as barras:Ela disse: "Java é legal!"C:\java\aulas
public class Main {
public static void main(String[] args) {
System.out.println("Ela disse: Java é legal!");
System.out.println("C:");
}
}
public class Main {
public static void main(String[] args) {
System.out.println("Ela disse: \"Java é legal!\"");
System.out.println("C:\\java\\aulas");
}
}
Todas as sequências de escape
O Java tem poucas sequências, e você vai usar de verdade só as quatro primeiras:
| Escape | Vira | Origem do nome | Uso |
|---|---|---|---|
\n | Quebra de linha | new line | Muito comum |
\t | Tab | tab | Alinhar colunas |
\" | Aspa dupla | Aspas dentro de String | |
\\ | Barra invertida | Caminhos do Windows, expressões regulares | |
\' | Aspa simples | No char '\'' | |
\r | Retorno de carro: volta ao começo da mesma linha | carriage return, das máquinas de escrever | Raro; o Windows termina linhas de arquivos com \r\n |
\b | Volta um caractere (backspace) | backspace | Raro |
\f | Avanço de página | form feed | Antigo, para impressoras |
\s | Um espaço Java 15+ | space | Nos Text Blocks |
\0 a \377 | O caractere com aquele código em octal (base 8) | Raríssimo: "\101" é "A" |
Qualquer outra letra depois da barra (\U, \D, \d, \w…) é um erro de compilação, como você vai ver adiante.
println já faz
System.out.println("oi") já pula a linha depois do texto (o "ln" é de line, veja Saída: print e println). Não precisa escrever "oi\n". Use \n para quebras no meio do texto, ou com print. Nos modelos de printf e format existe ainda o %n, que gera a quebra de linha certa para cada sistema operacional.
Escapes Unicode: \u
Todo caractere do mundo (letras de todos os alfabetos, acentos, símbolos, emojis) tem um número no padrão Unicode. Em Java, você pode escrever qualquer caractere pelo número, com \u seguido de exatamente 4 dígitos hexadecimais (base 16: 0–9 e a–f):
public class Main {
public static void main(String[] args) {
System.out.println("Caf\u00e9 com p\u00e3o");
char letra = '\u0041';
System.out.println(letra);
System.out.println("\u00c1gua, a\u00e7\u00facar e \u20ac 5");
System.out.println("Ol\u00E1");
System.out.println("\u2665");
}
}
$ java Main.java Café com pão A Água, açúcar e € 5 Olá ♥
| Escape | Caractere | Escape | Caractere |
|---|---|---|---|
\u00e1 | á | \u00c1 | Á |
\u00e3 | ã | \u00e9 | é |
\u00ea | ê | \u00ed | í |
\u00f3 | ó | \u00f5 | õ |
\u00fa | ú | \u00e7 | ç |
\u0041 | A | \u20ac | € |
Maiúsculas ou minúsculas nos dígitos tanto faz (\u00E1 = \u00e1). Hoje os editores e o JDK trabalham em UTF-8, então você pode simplesmente digitar "Café" no código, como fizemos o curso todo. Os escapes Unicode são úteis para caracteres invisíveis (como o "espaço largo" \u2003 da aula Métodos de String) ou que não estão no teclado.
A pegadinha: \u funciona até em comentários
Os escapes Unicode são diferentes dos outros: o javac os traduz antes de tudo, no arquivo inteiro, inclusive dentro de comentários. Por isso um comentário inocente com um caminho do Windows quebra a compilação. Este código tem um erro de propósito.
public class Main {
public static void main(String[] args) {
// os arquivos ficam em C:\users\ana
System.out.println("Oi");
}
}
$ javac Main.java
Main.java:3: error: illegal unicode escape
// os arquivos ficam em C:\users\ana
^
1 error
\users começa com \u, e sers não são 4 dígitos hexadecimais: "escape Unicode ilegal". Num comentário, escreva C:\\users, use / ou mude o texto.
Organizar a saída com \n e \t
Com quebras e tabs, um único texto vira uma pequena tabela. Isso é útil para relatórios simples:
public class Main {
public static void main(String[] args) {
System.out.println("Aluno\tNota\nAna\t9.5\nBruno\t7.0");
}
}
$ java Main.java Aluno Nota Ana 9.5 Bruno 7.0
O tab alinha bem enquanto os textos da primeira coluna são curtos (menos de 8 caracteres, no terminal). Com nomes longos, a coluna "pula" para o próximo ponto de tab e desalinha. Para colunas com largura exata, use printf com %-10s (veja Formatar Texto).
Brinque com o código: acrescente uma terceira coluna (\tSituação) e mais um aluno. Depois troque um nome por um bem comprido, como Maria Eduarda, e veja o que acontece com o alinhamento.
public class Main {
public static void main(String[] args) {
System.out.println("Aluno\tNota");
System.out.println("Ana\t9.5");
System.out.println("Bruno\t7.0");
}
}
Quando dá errado
error: illegal escape character
Este código tem um erro de propósito.
public class Main {
public static void main(String[] args) {
System.out.println("Pasta: C:\Documentos\Ana");
}
}
$ javac Main.java
Main.java:3: error: illegal escape character
System.out.println("Pasta: C:\Documentos\Ana");
^
Main.java:3: error: illegal escape character
System.out.println("Pasta: C:\Documentos\Ana");
^
2 errors
O que aconteceu: \D e \A não são sequências de escape ("caractere de escape ilegal"). Uma barra sozinha num texto sempre tenta formar uma sequência com o caractere seguinte. O ^ aponta para cada uma.
Como resolver: dobre as barras: "C:\\Documentos\\Ana". Em caminhos, o Java também aceita / no Windows: "C:/Documentos/Ana".
error: illegal unicode escape
Este código tem um erro de propósito.
public class Main {
public static void main(String[] args) {
System.out.println("Pasta: C:\users\ana");
}
}
$ javac Main.java
Main.java:3: error: illegal unicode escape
System.out.println("Pasta: C:\users\ana");
^
Main.java:3: error: illegal escape character
System.out.println("Pasta: C:\users\ana");
^
2 errors
O que aconteceu: \u anuncia um escape Unicode com 4 dígitos hexadecimais, e veio sers. O segundo erro é o \a, que também não existe. Lembre que o \u dá esse erro até em comentários.
Como resolver: \\users\\ana.
error: unclosed string literal
Este código tem um erro de propósito.
public class Main {
public static void main(String[] args) {
System.out.println("Olá, mundo!);
}
}
$ javac Main.java
Main.java:3: error: unclosed string literal
System.out.println("Olá, mundo!);
^
1 error
O que aconteceu: o texto foi aberto e nunca fechado na mesma linha ("literal de String não fechado"). O ^ aponta para a aspa que abriu. Um texto entre aspas comuns não pode atravessar linhas; se você apertar Enter no meio dele, o erro é o mesmo, uma vez para cada pedaço.
Como resolver: feche as aspas: "Olá, mundo!". Para quebrar a linha dentro do texto, use \n; para textos de várias linhas no código, Text Blocks. Outra causa comum: um \" no fim do texto, que vira aspa comum e deixa o texto aberto ("C:\pasta\").
error: empty character literal
Este código tem um erro de propósito.
public class Main {
public static void main(String[] args) {
char aspa = ''';
System.out.println(aspa);
}
}
$ javac Main.java
Main.java:3: error: empty character literal
char aspa = ''';
^
Main.java:7: error: reached end of file while parsing
2 errors
O que aconteceu: as duas primeiras aspas formaram um char vazio (''), que não existe ("literal de caractere vazio"). A terceira aspa abriu outro char que bagunçou o resto do arquivo, e o javac chegou ao fim (end of file) ainda procurando o fechamento.
Como resolver: char aspa = '\'';.
Referência
| Escrito no código | Aparece na tela |
|---|---|
"Ela disse \"oi\"" | Ela disse "oi" |
"C:\\Users" | C:\Users |
"um\ndois" | um (quebra) dois |
"A\tB" | A (tab) B |
'\'' | ' |
"Caf\u00e9" | Café |
"\\d+" (num padrão de regex) | o texto \d+ |
Exercícios
Missão final: com um único System.out.println, usando \t e \n, mostre a tabela:Aluno(tab)NotaAna(tab)9.5Bruno(tab)7.0
public class Main {
public static void main(String[] args) {
System.out.println("Aluno Nota");
}
}
public class Main {
public static void main(String[] args) {
System.out.println("Aluno\tNota\nAna\t9.5\nBruno\t7.0");
}
}
1. Aspas no texto
Complete para mostrar O livro "Dom Casmurro":
2. Barra de verdade
Complete para mostrar D:\fotos:
3. Quantos caracteres?
Quanto vale "1\t2".length()?
4. Por que "C:\Downloads" não compila?
5. Qual destes não compila?
Resumo
- A barra invertida
\junta-se ao caractere seguinte e forma um caractere especial (uma sequência de escape). \"= aspa dupla dentro do texto;\\= uma barra;\'= aspa simples (obrigatório só emchar).\nquebra a linha;\tavança até a próxima coluna.\u+ 4 dígitos hexadecimais = qualquer caractere Unicode, e funciona até em comentários (cuidado comC:\users).- Barra seguida de outra letra dá
illegal escape character; texto sem aspa de fechamento dáunclosed string literal.