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".

Você vai aprender
  • 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 literal e empty 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ê querDentro 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:

EscapeViraOrigem do nomeUso
\nQuebra de linhanew lineMuito comum
\tTabtabAlinhar colunas
\"Aspa duplaAspas dentro de String
\\Barra invertidaCaminhos do Windows, expressões regulares
\'Aspa simplesNo char '\''
\rRetorno de carro: volta ao começo da mesma linhacarriage return, das máquinas de escreverRaro; o Windows termina linhas de arquivos com \r\n
\bVolta um caractere (backspace)backspaceRaro
\fAvanço de páginaform feedAntigo, para impressoras
\sUm espaço Java 15+spaceNos Text Blocks
\0 a \377O 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.

Quebra de linha no fim: 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á
♥
EscapeCaractereEscapeCaractere
\u00e1á\u00c1Á
\u00e3ã\u00e9é
\u00eaê\u00edí
\u00f3ó\u00f5õ
\u00faú\u00e7ç
\u0041A\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ódigoAparece 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)Nota
Ana(tab)9.5
Bruno(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":

System.out.println("O livro ");

2. Barra de verdade

Complete para mostrar D:\fotos:

System.out.println("D:");

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ó em char).
  • \n quebra a linha; \t avança até a próxima coluna.
  • \u + 4 dígitos hexadecimais = qualquer caractere Unicode, e funciona até em comentários (cuidado com C:\users).
  • Barra seguida de outra letra dá illegal escape character; texto sem aspa de fechamento dá unclosed string literal.