Java Ler do Teclado (Scanner)

Até agora, os seus programas só falavam: tudo o que eles usavam estava escrito no código. Nesta aula eles começam a ouvir. Com a classe Scanner, o programa para, espera a pessoa digitar algo e apertar Enter, e usa o que foi digitado: um nome, uma idade, um preço.

Você vai aprender
  • Criar um Scanner que lê o teclado (System.in).
  • Ler uma linha de texto (nextLine), um inteiro (nextInt), um número com vírgula (nextDouble) e uma palavra (next).
  • Por que, no Brasil, o nextDouble quer vírgula (3,5) e falha com 3.5.
  • A pegadinha do nextInt seguido de nextLine, que todo iniciante encontra.
  • Validar a entrada com hasNextInt, sem o programa quebrar.
  • Fechar o Scanner e o cuidado com o System.in.
  • Testar programas que leem o teclado mandando a entrada pronta pelo terminal.

Os exemplos rodam no terminal da Ana (máquina fictícia notebook, pasta ~/java, JDK 25, idioma português do Brasil) com java Main.java. As sessões em que a Ana digita foram gravadas num terminal de verdade, então você vê o que ela digitou logo depois de cada pergunta.


A ideia antes do código

Pense numa atendente de balcão com um formulário. Ela faz uma pergunta, espera a resposta, anota no campo certo e só então passa para a próxima pergunta. Se o campo é "idade" e a pessoa responde "vinte", a atendente reclama.

No Java:

  • System.in ("entrada do sistema") é o teclado: um fluxo de caracteres que chegam um atrás do outro. Ele é o par do System.out que você já usa para escrever.
  • O Scanner ("leitor", "escaneador") é a atendente: lê esses caracteres, separa em pedaços e entrega cada pedaço já no tipo que você pediu (String, int, double).

O primeiro programa: ler o nome

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner teclado = new Scanner(System.in);
        System.out.print("Qual é o seu nome? ");
        String nome = teclado.nextLine();
        System.out.println("Olá, " + nome + "!");
        teclado.close();
    }
}
$ java Main.java
Qual é o seu nome? Ana Souza       « o programa parou aqui até a Ana digitar e apertar Enter
Olá, Ana Souza!
LinhaO que faz
import java.util.Scanner;O Scanner mora no pacote java.util. Esta linha avisa ao compilador que vamos usá-lo (veja Pacotes e import). Vem antes da classe.
Scanner teclado = new Scanner(System.in);Cria o leitor. Veja a anatomia logo abaixo.
System.out.print("Qual é o seu nome? ");A pergunta. Com print (sem "ln"), o cursor fica na mesma linha, e a resposta aparece ao lado da pergunta. O espaço no fim separa os dois.
String nome = teclado.nextLine();O programa para e espera. Quando a pessoa aperta Enter, tudo o que ela digitou na linha (com espaços) vira uma String, guardada em nome.
teclado.close();Fecha o leitor no fim, quando não vai mais ler nada (veja Fechar o Scanner).

Anatomia da criação

Scanner
O tipo da variável: um leitor.
teclado
O nome que você escolhe. teclado, entrada, sc e leitor são comuns.
= new Scanner(
Cria um Scanner novo (new = "novo"; você verá mais sobre isso em Classes e Objetos).
System.in);
De onde ler: o teclado.

Crie um Scanner no começo do programa e use o mesmo para todas as leituras.

Missão: complete o programa para ler o nome com nextLine e responder Bem-vinda, Ana Souza!. A entrada de teste já é "Ana Souza".

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner teclado = new Scanner(System.in);
        System.out.print("Nome: ");
        // leia o nome aqui

        System.out.println("Bem-vinda, " + "?" + "!");
        teclado.close();
    }
}
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner teclado = new Scanner(System.in);
        System.out.print("Nome: ");
        String nome = teclado.nextLine();
        System.out.println("Bem-vinda, " + nome + "!");
        teclado.close();
    }
}

Testar sem digitar: a entrada pelo terminal

Para não precisar digitar tudo a cada teste, você pode mandar a resposta pronta para o programa. O comando printf do terminal escreve o texto, e a barra vertical | ("cano", pipe) liga a saída dele à entrada do java. Cada \n é um Enter:

$ printf 'Ana Souza\n' | java Main.java
Qual é o seu nome? Olá, Ana Souza!

O programa é o mesmo, mas a resposta não aparece na tela e o "Olá" ficou grudado na pergunta. Por quê? Quando você digita, é o terminal que mostra as teclas (o "eco") e o Enter que pula a linha. Pelo |, ninguém digitou nada; o programa só recebeu os caracteres. O editor do guia funciona assim quando a caixa traz a entrada pronta: as respostas não aparecem no meio da saída.


Números: nextInt

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner teclado = new Scanner(System.in);
        System.out.print("Quantos anos você tem? ");
        int idade = teclado.nextInt();
        System.out.println("Ano que vem você terá " + (idade + 1) + " anos.");
        teclado.close();
    }
}
$ java Main.java
Quantos anos você tem? 29
Ano que vem você terá 30 anos.

O nextInt lê um número inteiro e já o entrega como int, pronto para contas. Com nextLine você receberia o texto "29", e "29" + 1 daria "291" (veja Concatenação).

Quando a pessoa digita outra coisa

$ java Main.java
Quantos anos você tem? vinte
Exception in thread "main" java.util.InputMismatchException
	at java.base/java.util.Scanner.throwFor(Scanner.java:977)
	at java.base/java.util.Scanner.next(Scanner.java:1632)
	at java.base/java.util.Scanner.nextInt(Scanner.java:2297)
	at java.base/java.util.Scanner.nextInt(Scanner.java:2251)
	at Main.main(Main.java:7)

InputMismatchException quer dizer "exceção de entrada incompatível": o nextInt esperava um inteiro e encontrou "vinte". O programa termina ali. As linhas com java.base são o caminho dentro do próprio Scanner; a que importa é a última: Main.java:7, a linha do nextInt. Mais adiante você aprende a validar para isso não acontecer.

Vários números na mesma linha

O nextInt pega o próximo número, esteja ele na mesma linha ou na seguinte. Espaços e Enter são só separadores:

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner teclado = new Scanner(System.in);
        System.out.print("Digite três números: ");
        int a = teclado.nextInt();
        int b = teclado.nextInt();
        int c = teclado.nextInt();
        System.out.println("Soma: " + (a + b + c));
        teclado.close();
    }
}
$ printf '4 5 6\n' | java Main.java
Digite três números: Soma: 15

Números com vírgula: nextDouble e o jeito brasileiro

O nextDouble lê um número decimal. Mas atenção: o Scanner segue o idioma e o país configurados no computador (o locale). Na máquina da Ana, que está em português do Brasil (pt_BR), o separador decimal é a vírgula, como nos documentos brasileiros.

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner teclado = new Scanner(System.in);
        System.out.print("Preço do quilo: ");
        double preco = teclado.nextDouble();
        System.out.print("Quantos quilos: ");
        double quilos = teclado.nextDouble();
        System.out.println("Total: R$ " + preco * quilos);
        teclado.close();
    }
}

Digitando com vírgula, funciona:

$ java Main.java
Preço do quilo: 3,5
Quantos quilos: 2
Total: R$ 7.0

Repare num detalhe curioso: a Ana digitou com vírgula, mas o println mostrou 7.0, com ponto. O Scanner segue o locale; o println de um double, não (já o printf segue: veja Formatar Texto).

Agora, digitando como num programa americano, com ponto:

$ java Main.java
Preço do quilo: 3.5
Exception in thread "main" java.util.InputMismatchException
	at java.base/java.util.Scanner.throwFor(Scanner.java:977)
	at java.base/java.util.Scanner.next(Scanner.java:1632)
	at java.base/java.util.Scanner.nextDouble(Scanner.java:2603)
	at Main.main(Main.java:7)

Para o Scanner brasileiro, 3.5 não é um número: no Brasil, o ponto separa os milhares (1.000), e "3.5" não faz sentido assim. Resultado: InputMismatchException na linha 7, a do nextDouble. Esse é um dos erros mais comuns de quem aprende Java no Brasil, porque os livros e vídeos em inglês sempre digitam com ponto.

Duas soluções

1. Digitar do jeito do locale: 3,5. Simples, mas depende do computador onde o programa roda: na máquina de alguém configurada em inglês, a vírgula é que daria erro.

2. Fixar o locale do Scanner com useLocale ("usar o locale"). Com Locale.US (Estados Unidos), o ponto passa a ser o separador, em qualquer computador:

import java.util.Locale;
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner teclado = new Scanner(System.in);
        teclado.useLocale(Locale.US);
        System.out.print("Preço do quilo: ");
        double preco = teclado.nextDouble();
        System.out.print("Quantos quilos: ");
        double quilos = teclado.nextDouble();
        System.out.println("Total: R$ " + preco * quilos);
        teclado.close();
    }
}
$ java Main.java
Preço do quilo: 3.5
Quantos quilos: 2
Total: R$ 7.0
import java.util.Locale;
A classe Locale (idioma + país) também precisa de import.
teclado.useLocale(
Muda as regras de leitura deste Scanner, logo depois de criá-lo.
Locale.US);
As regras dos Estados Unidos: ponto decimal.

A troca vale para os dois lados: com Locale.US, quem digitar 3,5 recebe o InputMismatchException (conferido no laboratório). Escolha um padrão e diga ao usuário qual é ("Preço (use ponto): ").

ScannerDigitar 3,5Digitar 3.5
Padrão, num computador em pt_BRfuncionaInputMismatchException
Com useLocale(Locale.US)InputMismatchExceptionfunciona

Uma palavra: next

O next lê só até o próximo espaço: uma palavra. O resto da linha fica esperando a próxima leitura:

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner teclado = new Scanner(System.in);
        System.out.print("Nome completo (com next): ");
        String primeiro = teclado.next();
        System.out.println("O next leu: [" + primeiro + "]");
        String resto = teclado.nextLine();
        System.out.println("Sobrou na linha: [" + resto + "]");
        teclado.close();
    }
}
$ java Main.java
Nome completo (com next): Ana Souza
O next leu: [Ana]
Sobrou na linha: [ Souza]    « o nextLine pegou o resto, com o espaço da frente

Os colchetes na mensagem são só para você enxergar onde o texto começa e termina. O next é útil para respostas de uma palavra ("sim", "não", um código); para nomes e frases, use nextLine.


A pegadinha do nextInt seguido de nextLine

Este é o problema mais famoso do Scanner. O cadastro pede a idade e depois o nome:

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner teclado = new Scanner(System.in);
        System.out.print("Idade: ");
        int idade = teclado.nextInt();
        System.out.print("Nome: ");
        String nome = teclado.nextLine();
        System.out.println("Cadastro: [" + nome + "], " + idade + " anos");
        teclado.close();
    }
}
$ java Main.java
Idade: 29
Nome: Cadastro: [], 29 anos  « não esperou o nome! e o nome ficou vazio

A Ana digitou 29 e apertou Enter. O programa mostrou "Nome:" e, sem esperar, já terminou com o nome vazio. Nada de erro, nada de exceção. O que aconteceu?

O que o teclado mandou

Quando a Ana digitou 29 e apertou Enter, chegaram ao programa três caracteres: 2, 9 e a quebra de linha (o Enter, que no Java se escreve \n):

PassoEntrada que sobraO que acontece
Início2 9 \nA Ana digitou "29" e Enter.
nextInt()\nPega só os dígitos (29). O \n fica lá.
nextLine()(nada)Lê "até o fim da linha". O fim da linha já está ali: lê um texto vazio e consome o \n. Não precisa esperar.

O nextInt (e também nextDouble e next) lê o número e não a quebra de linha que veio depois dele. O nextLine seguinte encontra essa sobra e acha que a linha acabou.

Solução 1: um nextLine() extra para "limpar" a linha

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner teclado = new Scanner(System.in);
        System.out.print("Idade: ");
        int idade = teclado.nextInt();
        teclado.nextLine();
        System.out.print("Nome: ");
        String nome = teclado.nextLine();
        System.out.println("Cadastro: [" + nome + "], " + idade + " anos");
        teclado.close();
    }
}
$ java Main.java
Idade: 29
Nome: Ana Souza
Cadastro: [Ana Souza], 29 anos

O teclado.nextLine(); solto, sem guardar o resultado, serve só para consumir o \n que sobrou. Ele vai logo depois de cada nextInt/nextDouble que é seguido de um nextLine.

Solução 2: ler tudo com nextLine e converter

Outra estratégia, muito usada: ler sempre linhas inteiras e transformar em número quando precisar, com Integer.parseInt ("interpretar como inteiro"; para decimais, Double.parseDouble). Assim nunca sobra nada na linha:

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner teclado = new Scanner(System.in);
        System.out.print("Idade: ");
        int idade = Integer.parseInt(teclado.nextLine());
        System.out.print("Nome: ");
        String nome = teclado.nextLine();
        System.out.println("Cadastro: [" + nome + "], " + idade + " anos");
        teclado.close();
    }
}
$ printf '29\nAna Souza\n' | java Main.java
Idade: Nome: Cadastro: [Ana Souza], 29 anos

Se a pessoa digitar algo que não é número, o erro muda de nome: NumberFormatException ("formato de número inválido"), com o texto culpado na mensagem:

$ printf 'vinte\nAna\n' | java Main.java
Idade: Exception in thread "main" java.lang.NumberFormatException: For input string: "vinte"
	at java.base/java.lang.NumberFormatException.forInputString(NumberFormatException.java:67)
	at java.base/java.lang.Integer.parseInt(Integer.java:565)
	at java.base/java.lang.Integer.parseInt(Integer.java:662)
	at Main.main(Main.java:7)

O Integer.parseInt aparece de novo, com mais detalhes, em Argumentos da Linha de Comando e em Wrappers. Diferente do nextDouble, o Double.parseDouble não segue o locale: ele sempre quer ponto ("3.5").

Missão: este é o programa com a pegadinha. Rode e veja o nome sair vazio. Depois conserte com uma das duas soluções, para a saída terminar com Cadastro: [Ana Souza], 29 anos. A entrada de teste é 29 e depois Ana Souza.

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner teclado = new Scanner(System.in);
        System.out.print("Idade: ");
        int idade = teclado.nextInt();
        System.out.print("Nome: ");
        String nome = teclado.nextLine();
        System.out.println("Cadastro: [" + nome + "], " + idade + " anos");
        teclado.close();
    }
}
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner teclado = new Scanner(System.in);
        System.out.print("Idade: ");
        int idade = teclado.nextInt();
        teclado.nextLine();
        System.out.print("Nome: ");
        String nome = teclado.nextLine();
        System.out.println("Cadastro: [" + nome + "], " + idade + " anos");
        teclado.close();
    }
}

Validar com hasNextInt

Em vez de deixar o programa quebrar com InputMismatchException, dá para perguntar antes. O hasNextInt() ("tem um próximo inteiro?") olha o que vem pela frente, sem consumir nada, e responde true ou false:

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner teclado = new Scanner(System.in);
        System.out.print("Quantos anos você tem? ");
        while (!teclado.hasNextInt()) {
            String errado = teclado.next();
            System.out.print("\"" + errado + "\" não é um número inteiro. Tente de novo: ");
        }
        int idade = teclado.nextInt();
        System.out.println("Ano que vem você terá " + (idade + 1) + " anos.");
        teclado.close();
    }
}
$ java Main.java
Quantos anos você tem? vinte
"vinte" não é um número inteiro. Tente de novo: 2.5
"2.5" não é um número inteiro. Tente de novo: 29
Ano que vem você terá 30 anos.
LinhaO que faz
while (!teclado.hasNextInt())"Enquanto o que vem não for um inteiro" (o ! inverte, veja Operadores Lógicos). O hasNextInt espera a pessoa digitar, se ainda não houver nada.
String errado = teclado.next();Essencial: tira a palavra errada da entrada. Sem esta linha, o hasNextInt veria o mesmo "vinte" para sempre: laço infinito.
System.out.print(…)Avisa e pede de novo. O \" põe aspas dentro do texto (veja Caracteres Especiais).
int idade = teclado.nextInt();Só chega aqui quando o próximo item é um inteiro: agora o nextInt não falha.

Existe um hasNext… para cada next…: hasNextDouble(), hasNextLine(), hasNext()… Validar faixas (idade entre 1 e 120) é outra etapa, feita com if ou com o do-while que você viu em while e do-while. Tratar a exceção com try/catch é a outra forma de lidar com entradas erradas, assunto de try e catch.


Ler num laço: preencher um array

O Scanner combina com os laços. A professora digita as notas de 3 alunos:

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner teclado = new Scanner(System.in);
        int[] notas = new int[3];
        for (int i = 0; i < notas.length; i++) {
            System.out.print("Nota do aluno " + (i + 1) + ": ");
            notas[i] = teclado.nextInt();
        }
        int soma = 0;
        for (int nota : notas) {
            soma += nota;
        }
        System.out.println("Média: " + (double) soma / notas.length);
        teclado.close();
    }
}
$ printf '7\n8\n10\n' | java Main.java
Nota do aluno 1: Nota do aluno 2: Nota do aluno 3: Média: 8.333333333333334

(Veja Arrays e Percorrer Arrays.) E se a entrada acabar antes? Com só duas notas:

$ printf '7\n8\n' | java Main.java
Nota do aluno 1: Nota do aluno 2: Nota do aluno 3: Exception in thread "main" java.util.NoSuchElementException
	at java.base/java.util.Scanner.throwFor(Scanner.java:975)
	at java.base/java.util.Scanner.next(Scanner.java:1632)
	at java.base/java.util.Scanner.nextInt(Scanner.java:2297)
	at java.base/java.util.Scanner.nextInt(Scanner.java:2251)
	at Main.main(Main.java:9)

NoSuchElementException = "não existe o próximo elemento": a entrada terminou e o programa ainda queria ler. No terminal, a pessoa encerra a entrada apertando Ctrl+D no Linux e no macOS (Ctrl+Z e Enter no Windows). Com o nextLine, a mensagem traz um detalhe: No line found ("nenhuma linha encontrada").


Fechar o Scanner

O teclado.close() diz "terminei de ler". É uma boa prática fechar o que você abriu, e algumas IDEs mostram um aviso amarelo ("resource leak", vazamento de recurso) quando um Scanner nunca é fechado.

Mas atenção: fechar o Scanner fecha também o System.in, e o teclado não pode ser reaberto. Um segundo Scanner criado depois não consegue ler nada:

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner primeiro = new Scanner(System.in);
        System.out.print("Nome: ");
        String nome = primeiro.nextLine();
        primeiro.close();
        Scanner segundo = new Scanner(System.in);
        System.out.print("Cidade: ");
        String cidade = segundo.nextLine();
        System.out.println(nome + " mora em " + cidade);
    }
}
$ printf 'Ana\nRecife\n' | java Main.java
Nome: Cidade: Exception in thread "main" java.util.NoSuchElementException: No line found
	at java.base/java.util.Scanner.nextLine(Scanner.java:1690)
	at Main.main(Main.java:11)

A cidade estava lá, mas o System.in já tinha sido fechado. A regra: um Scanner só, criado no começo, fechado no fim (ou nem fechado, num programa pequeno que termina logo depois; ao terminar, o sistema libera tudo).

Há também uma forma que fecha sozinha, o try com recursos (try-with-resources), explicado em finally e try-with-resources:

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        try (Scanner teclado = new Scanner(System.in)) {
            System.out.print("Qual é o seu nome? ");
            String nome = teclado.nextLine();
            System.out.println("Olá, " + nome + "!");
        }
    }
}

Outra forma no Java 25: IO.readln Java 25+

O Java 25 trouxe os "arquivos-fonte compactos": um main mais curto, sem public class, e a classe IO com métodos simples para escrever e ler. O IO.readln mostra a pergunta e lê uma linha, tudo junto:

void main() {
    String nome = IO.readln("Qual é o seu nome? ");
    IO.println("Olá, " + nome + "!");
}
$ printf 'Ana\n' | java Main.java
Qual é o seu nome? Olá, Ana!

Ele só lê linhas de texto (para números, combine com Integer.parseInt) e não existe antes do Java 25. Em código "de verdade" e em qualquer versão anterior, o Scanner continua sendo o padrão, e é ele que você vai encontrar nos livros, nas empresas e no restante deste guia. (Mais sobre o main compacto em Olá, Mundo e em Novidades do Java 17 ao 25.)


Qual método usar

Quero ler…UseDigitadoRecebe
Uma linha inteira (nome, frase)nextLine()Ana Souza"Ana Souza"
Uma palavranext()Ana Souza"Ana"
Um inteironextInt()2929
Um inteiro grandenextLong()90000000009000000000L
Um decimalnextDouble()3,5 (pt_BR)3.5
Verdadeiro ou falsonextBoolean()truetrue
Saber se vem um inteirohasNextInt()true/false

Quando dá errado

"cannot find symbol … class Scanner"
public class Main {
    public static void main(String[] args) {
        Scanner teclado = new Scanner(System.in);
        String nome = teclado.nextLine();
    }
}
$ java Main.java
Main.java:3: error: cannot find symbol
        Scanner teclado = new Scanner(System.in);
        ^
  symbol:   class Scanner
  location: class Main
Main.java:3: error: cannot find symbol
        Scanner teclado = new Scanner(System.in);
                              ^
  symbol:   class Scanner
  location: class Main
2 errors
error: compilation failed

O que quer dizer: o compilador não conhece a classe Scanner: dois erros, um para cada vez que o nome aparece na linha.

Como consertar: import java.util.Scanner; na primeira linha.

InputMismatchException

O que aconteceu: o nextInt/nextDouble encontrou algo que não é um número daquele tipo: texto ("vinte"), decimal num nextInt ("2.5"), ou o separador decimal errado para o locale ("3.5" num Scanner pt_BR).

Como resolver: digite no formato certo; use useLocale(Locale.US) se quiser ponto decimal; e valide com hasNextInt/hasNextDouble antes de ler.

O programa "pulou" uma pergunta (o texto veio vazio)

Um nextLine logo depois de um nextInt, nextDouble ou next lê a sobra da linha anterior. Coloque um teclado.nextLine(); extra entre eles, ou leia tudo com nextLine e converta. Veja a pegadinha.

NoSuchElementException ("No line found")

O que aconteceu: a entrada acabou antes do que o programa esperava: a pessoa apertou Ctrl+D, faltaram linhas no printf … |, ou o System.in foi fechado por um close() anterior.

Como resolver: mande toda a entrada, use um único Scanner e só o feche no fim. Para ler "até a entrada acabar", use while (teclado.hasNextLine()).

O programa parou e não acontece nada

Provavelmente ele está esperando você digitar. Um nextLine sem um print antes não mostra pergunta nenhuma; o cursor só fica piscando. Digite a resposta e aperte Enter, e sempre escreva uma pergunta antes de cada leitura. (Se nem digitando ele responde, pode ser um laço infinito: veja while.)


Referência

CódigoO que faz
import java.util.Scanner;Permite usar o Scanner
Scanner sc = new Scanner(System.in);Cria o leitor do teclado (um por programa)
sc.nextLine()Lê o resto da linha, até o Enter (que é descartado)
sc.next()Lê a próxima palavra
sc.nextInt(), nextLong(), nextDouble(), nextBoolean()Lê o próximo item já convertido; deixa o \n na entrada
sc.hasNextInt(), hasNextDouble(), hasNextLine()Pergunta se o próximo item é daquele tipo, sem consumir
sc.useLocale(Locale.US)Passa a usar ponto decimal na leitura
sc.close()Fecha o Scanner e o System.in
Integer.parseInt(texto), Double.parseDouble(texto)Convertem texto em número (o parseDouble sempre usa ponto)
printf 'a\nb\n' | java Main.javaNo terminal: manda a entrada pronta para o programa

Exercícios

1. Criar o leitor

Complete para criar um Scanner que lê o teclado:

Scanner teclado = new Scanner();

2. Ler um inteiro

Complete para ler a quantidade como int:

int quantidade = teclado.;

3. Limpar a linha

Depois de int idade = teclado.nextInt();, qual instrução evita que o próximo nextLine venha vazio?

4. Num computador em português do Brasil, a pessoa digita 2.5 num nextDouble() sem useLocale. O que acontece?

5. A pessoa digita Ana Maria. O que teclado.next() devolve?

6. No laço de validação com hasNextInt, por que é preciso chamar teclado.next() quando a entrada é inválida?

7. O que acontece se você fechar o Scanner e depois criar outro com new Scanner(System.in)?

Missão final: o programa lê primeiro quantos números virão e depois cada número, e mostra Soma: com o total. A entrada de teste é 3 (a quantidade) e os números 10, 20 e 5. Use um for que repete a leitura a quantidade de vezes.

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner teclado = new Scanner(System.in);
        System.out.print("Quantos números? ");
        int quantidade = teclado.nextInt();
        int soma = 0;
        // leia e some os números aqui

        System.out.println("Soma: " + soma);
        teclado.close();
    }
}
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner teclado = new Scanner(System.in);
        System.out.print("Quantos números? ");
        int quantidade = teclado.nextInt();
        int soma = 0;
        for (int i = 1; i <= quantidade; i++) {
            System.out.print("Número " + i + ": ");
            soma += teclado.nextInt();
        }
        System.out.println("Soma: " + soma);
        teclado.close();
    }
}

Resumo

  • import java.util.Scanner; e Scanner teclado = new Scanner(System.in);: um leitor só, para o programa todo.
  • nextLine() lê a linha inteira; next(), uma palavra; nextInt()/nextDouble(), números já convertidos.
  • Num computador em pt_BR, o nextDouble quer vírgula; 3.5 dá InputMismatchException. Para usar ponto: teclado.useLocale(Locale.US).
  • nextInt seguido de nextLine: o nextLine vem vazio. Use um nextLine() extra ou leia tudo com nextLine + Integer.parseInt.
  • Valide com hasNextInt() antes de ler, e descarte a entrada errada com next().
  • Fechar o Scanner fecha o System.in para sempre: feche só no fim.
  • Teste mandando a entrada pronta: printf 'Ana\n29\n' | java Main.java.