Java Saída: print e println

Escrever na tela é a forma mais simples de um programa mostrar o que fez. Você já usou o System.out.println; nesta aula você conhece o irmão dele, o print, aprende a mostrar números e contas (e a não cair na armadilha do "3" + 4), a pular linhas, a separar mensagens de erro com o System.err e a reconhecer o IO.println e o printf.

Você vai aprender
  • A diferença entre println e print, e como fazer uma linha em branco.
  • Como imprimir números, contas e textos juntos.
  • Por que println(3 + 4) mostra 7 e println("3" + 4) mostra 34.
  • Quebras de linha e tabulação com \n e \t.
  • A saída de erro, System.err, e por que ela existe.
  • IO.println Java 25+ e o printf, só para conhecer.

A ideia: uma máquina de escrever

Imagine uma máquina de escrever antiga. Você datilografa letras numa linha. Quando quer passar para a linha de baixo, puxa a alavanca que faz o papel subir e o carro voltar ao começo. Escrever na tela do terminal é igual: o texto vai entrando da esquerda para a direita, e só passa para a próxima linha quando alguém manda.

  • System.out.print só datilografa: escreve e deixa o "carro" parado logo depois do texto.
  • System.out.println datilografa e puxa a alavanca: escreve e pula para o começo da próxima linha. O ln do nome é de line, "linha".

println: escrever e pular linha

System.out.println("Loja da Ana");
System.out
A saída padrão do programa: normalmente, a janela do terminal (ou a área de saída do editor do guia).
.println
O método que escreve e pula linha.
("Loja da Ana")
O que escrever: um texto entre aspas, um número, uma conta, uma variável.

Cada println ocupa uma linha da saída. Três println, três linhas. E um println() vazio, sem nada entre os parênteses, só pula linha: é o jeito de fazer uma linha em branco.

public class Main {
    public static void main(String[] args) {
        System.out.println("Loja da Ana");
        System.out.println();
        System.out.println("Maçã: 3 reais");
        System.out.println("Banana: 2 reais");
    }
}
$ java Main.java
Loja da Ana
                                « a linha em branco do println()
Maçã: 3 reais
Banana: 2 reais

print: escrever sem pular

O print escreve e fica na mesma linha. O próximo texto continua colado:

public class Main {
    public static void main(String[] args) {
        System.out.print("Maçã");
        System.out.print("Banana");
        System.out.println("Uva");
        System.out.println("Fim da lista");
    }
}
$ java Main.java
MaçãBananaUva                   « três textos colados: print, print, println
Fim da lista

O print não põe espaço nenhum entre os textos: se você quer separação, ela tem de estar no texto ("Maçã, "). Só o println("Uva") pulou a linha, por isso Fim da lista foi para baixo.

Se o programa termina com um print, a última linha fica sem quebra, e o prompt do terminal aparece colado a ela:

$ java Main.java
sem enter no fimana@notebook:~$  « o prompt veio colado no texto

Por isso, a última escrita de um programa costuma ser um println. O print é ótimo para montar uma linha aos poucos e para perguntas, em que a resposta é digitada na mesma linha (System.out.print("Seu nome: ");, veja Ler do Teclado).

Missão: faça o programa mostrar Frutas: maçã, banana, uva numa linha só. Use print nas primeiras linhas e println só na última. Atenção às vírgulas e aos espaços dentro das aspas.

public class Main {
    public static void main(String[] args) {
        System.out.println("Frutas: ");
        System.out.println("maçã");
        System.out.println("banana");
        System.out.println("uva");
    }
}
public class Main {
    public static void main(String[] args) {
        System.out.print("Frutas: ");
        System.out.print("maçã, ");
        System.out.print("banana, ");
        System.out.println("uva");
    }
}

Imprimir números e contas

O println aceita mais do que texto. Sem aspas, o Java calcula antes de escrever:

public class Main {
    public static void main(String[] args) {
        System.out.println(3 + 4);
        System.out.println("3 + 4");
        System.out.println(7 / 2);
        System.out.println(7.0 / 2);
        System.out.println(10 * 1.5);
        System.out.println(true);
    }
}
$ java Main.java
7                               « 3 + 4 sem aspas: uma conta
3 + 4                           « com aspas: um texto, escrito do jeito que está
3                               « inteiro dividido por inteiro: a parte decimal some
3.5                             « com um decimal na conta, o resultado é decimal
15.0                            « decimal sempre aparece com ponto e pelo menos uma casa
true                            « um valor lógico (verdadeiro)

Três lições aparecem aqui e têm aulas próprias: a divisão de inteiros (Operadores Aritméticos), os números com parte decimal, escritos com ponto (double e float), e os valores true/false (char e boolean).


Texto + número: a armadilha do "3" + 4

O sinal + tem dois trabalhos em Java. Entre dois números, soma. Se um dos lados é um texto, ele emenda (o nome técnico é concatenar): transforma o outro lado em texto e cola os dois. E o Java faz as operações da esquerda para a direita, uma de cada vez. Veja:

public class Main {
    public static void main(String[] args) {
        System.out.println("3" + 4);
        System.out.println("Total: " + 3 + 4);
        System.out.println("Total: " + (3 + 4));
        System.out.println(3 + 4 + " reais");
        System.out.println(1 + 2 + "3" + 4 + 5);
    }
}
$ java Main.java
34                              « texto "3" emendado com 4
Total: 34                       « ("Total: " + 3) virou texto; depois + 4 emendou
Total: 7                        « os parênteses fazem a soma primeiro
7 reais                         « 3 + 4 = 7 (números), depois emenda " reais"
3345                            « 1+2=3; "3"+"3"="33"; depois só emendas: "334", "3345"

Acompanhe a segunda linha passo a passo, como o Java faz:

  1. "Total: " + 3: texto + número = emenda. Resultado: o texto "Total: 3".
  2. "Total: 3" + 4: texto + número = emenda de novo. Resultado: "Total: 34".

A soma que você queria nunca aconteceu. A solução é a terceira linha: parênteses em volta da conta, que é feita primeiro. Regra prática: sempre que misturar texto e conta, ponha a conta entre parênteses. A aula Concatenação aprofunda o assunto.

Missão: a Ana comprou 10 reais em frutas e pagou 5 de entrega, mas o programa mostra Total do pedido: 105 reais. Conserte para mostrar Total do pedido: 15 reais, sem trocar os números.

public class Main {
    public static void main(String[] args) {
        System.out.println("Total do pedido: " + 10 + 5 + " reais");
    }
}
public class Main {
    public static void main(String[] args) {
        System.out.println("Total do pedido: " + (10 + 5) + " reais");
    }
}

Quebras de linha e tabulação dentro do texto

Dentro das aspas, a barra invertida \ começa um código de escape, que representa um caractere especial. Os mais usados na saída:

CódigoViraExemploSaída
\nQuebra de linha (new line)print("Linha 1\nLinha 2\n")Duas linhas
\tTabulação (tab), um espaço largo para alinharprintln("Nome:\tAna")Nome: Ana
\"Uma aspa dupla dentro do textoprintln("Ela disse \"oi\"")Ela disse "oi"
\\Uma barra invertidaprintln("C:\\java")C:\java
public class Main {
    public static void main(String[] args) {
        System.out.print("Linha 1\nLinha 2\n");
        System.out.println("Nome:\tAna");
        System.out.println("Ela disse \"oi\"");
    }
}
$ java Main.java
Linha 1
Linha 2                         « o \n quebrou a linha no meio do texto
Nome:	Ana                       « o \t abriu um espaço de tabulação
Ela disse "oi"

Um print("…\n") faz o mesmo que um println("…"). A lista completa de códigos está em Caracteres Especiais.


A saída de erro: System.err

Todo programa tem duas saídas de texto: a saída padrão (System.out, de output) e a saída de erro (System.err, de error). As duas aparecem na mesma tela do terminal, mas são canais separados, como duas mangueiras que desembocam no mesmo balde. Os métodos são os mesmos: println, print.

public class Main {
    public static void main(String[] args) {
        System.out.println("Começando...");
        System.err.println("Aviso: estoque de maçãs baixo");
        System.out.println("Fim.");
    }
}
$ java Main
Começando...
Aviso: estoque de maçãs baixo
Fim.

Na tela, as três linhas parecem iguais. A diferença aparece quando a saída é separada. No terminal, 2>/dev/null joga fora a saída de erro, e >/dev/null joga fora a saída padrão:

$ java Main 2>/dev/null
Começando...                    « só a saída padrão (System.out)
Fim.
$ java Main >/dev/null
Aviso: estoque de maçãs baixo   « só a saída de erro (System.err)

Para que isso serve? Quando a saída de um programa é gravada num arquivo ou passada a outro programa (por exemplo, java Relatorio > relatorio.txt), as mensagens de erro e avisos continuam aparecendo na tela, em vez de se misturarem com o resultado. Regra: resultados no System.out; erros e avisos no System.err. As mensagens de exceção do próprio Java (Exception in thread "main"…) também vão para a saída de erro. No editor do guia, a saída de erro aparece destacada.

A ordem pode embaralhar

Como são dois canais, quando os dois escrevem muito ao mesmo tempo, as linhas de out e err podem aparecer fora da ordem do código em alguns terminais e IDEs. Não use System.err para texto normal só porque aparece em vermelho na IDE.

Missão: a mensagem de erro está saindo pela saída normal. Faça a linha Erro: produto não encontrado sair pela saída de erro.

public class Main {
    public static void main(String[] args) {
        System.out.println("Buscando produto...");
        System.out.println("Erro: produto não encontrado");
    }
}
public class Main {
    public static void main(String[] args) {
        System.out.println("Buscando produto...");
        System.err.println("Erro: produto não encontrado");
    }
}

Outras formas de escrever

IO.println Java 25+

O Java 25 trouxe a classe IO, com métodos curtos para entrada e saída: IO.println(…) e IO.print(…) fazem o mesmo que System.out.println e System.out.print. Ela aparece principalmente na forma simplificada do main (veja Olá, Mundo), mas funciona em qualquer programa Java 25:

IO.println("Olá do IO");
IO.print("sem quebra");
IO.println();
$ java Main.java
Olá do IO
sem quebra

Em versões anteriores ao 25, IO não existe e o javac responde cannot find symbol. Por isso o guia usa System.out.println.

printf: escrever com formato

Para controlar casas decimais e alinhar colunas, existe o printf (de print formatted, "imprimir formatado"). Um exemplo, só para você reconhecer:

System.out.printf("Média: %.2f%n", 7.456);
$ java Main.java
Média: 7,46                     « duas casas decimais; com VÍRGULA, porque o sistema está em português

O %.2f quer dizer "um número decimal com 2 casas", e o %n pula linha. Repare na vírgula: o printf segue o idioma do sistema (aqui, português do Brasil), enquanto o println(7.456) sempre usa ponto. Tudo sobre o printf está em Formatar Texto.

Qual usar?

Quero…Use
Escrever uma linha completaSystem.out.println(…)
Escrever e continuar na mesma linha (perguntas, listas montadas aos poucos)System.out.print(…)
Uma linha em brancoSystem.out.println()
Várias linhas num texto só\n dentro das aspas (ou um text block)
Mensagens de erro e avisosSystem.err.println(…)
Casas decimais e colunas alinhadasSystem.out.printf(…)
Programa curto no Java 25IO.println(…)

Quando dá errado

bad operand types for binary operator '-'
$ javac Main.java
Main.java:3: error: bad operand types for binary operator '-'
        System.out.println("Total: " + 10 - 3);
                                          ^
  first type:  String
  second type: int
1 error

O que aconteceu: a mesma armadilha do "3" + 4, agora com subtração. Da esquerda para a direita: "Total: " + 10 virou o texto "Total: 10"; depois, "Total: 10" - 3: não existe "texto menos número". A mensagem diz "tipos de operandos inválidos para o operador -: o primeiro é String, o segundo é int". Como resolver: parênteses: "Total: " + (10 - 3).

Texto sem aspas: cannot find symbol
$ javac Main.java
Main.java:3: error: cannot find symbol
        System.out.println(Olá);
                           ^
  symbol:   variable Olá
  location: class Main
1 error

O que aconteceu: sem aspas, Olá não é um texto: o Java acha que é o nome de uma variável e não encontra nenhuma com esse nome. Como resolver: System.out.println("Olá");.

Duas coisas separadas por vírgula: no suitable method found
$ javac Main.java
Main.java:3: error: no suitable method found for println(String,String)
        System.out.println("Ana", "Bruno");
                  ^
    method PrintStream.println() is not applicable
      (actual and formal argument lists differ in length)
    method PrintStream.println(boolean) is not applicable
      (actual and formal argument lists differ in length)
…                               « o javac lista as 10 versões do println, uma por uma
1 error

O que aconteceu: o println recebe uma coisa só. Com vírgula, você passou duas, e o javac diz "nenhum método adequado para println(String,String)", listando todas as versões de println que existem (com nada, com um boolean, com um int…) e explicando que em todas "as listas de argumentos têm tamanhos diferentes". Como resolver: emende com +: System.out.println("Ana" + " e " + "Bruno");.


Exercícios

1. Linha em branco

Complete para escrever uma linha em branco:

System.out.

2. O que aparece?

O que System.out.println("5" + 5); mostra?

3. E este?

O que System.out.println(5 + 5 + "5"); mostra?

4. Qual a diferença entre print e println?

5. Qual linha mostra Total: 7?

6. Para onde devem ir as mensagens de erro de um programa?


Resumo

  • System.out.println(x) escreve e pula linha; System.out.print(x) escreve e fica na linha; println() faz uma linha em branco.
  • Sem aspas, o Java calcula: println(3 + 4) mostra 7. Com aspas, é texto: "3 + 4".
  • + com texto emenda, da esquerda para a direita: "Total: " + 3 + 4 dá Total: 34. Ponha contas entre parênteses.
  • \n quebra a linha e \t tabula dentro do texto.
  • System.err é a saída de erro: separada da saída normal, para avisos e erros.
  • IO.println Java 25+ faz o mesmo que System.out.println; printf formata números (com vírgula em português).