NoSuchElementeException - Scanner

Olá. Estou estudando a classe scanner e me deparei com o seguinte problema.

Tenho uma única classe onde criei o construtor e a main para chama-lo. O objetivo do código é pedir duas informações ao usuário e depois mostrar na tela.

Ao executar o codigo ele funciona corretamente na primeira chamado do metodo AgcC, mas dá erro ao executar na segunda vez. Qual o mistério?

import java.util.Scanner;

public class scanner {

private static int agenciaM ;

private static int ccM ;

public static void main(String[] args) {

AgCc ();

System. out .println("Agencia / Conta: " + agenciaM + " / " + ccM );

AgCc ();

System. out .println("Agencia / Conta: " + agenciaM + " / " + ccM );

}

public static void AgCc() {

Scanner s1 = new Scanner(System. in );

System. out .println("Digite o numero da agencia: ");

agenciaM = s1.nextInt();

System. out .println("Digite o numero da conta corrente: ");

ccM = s1.nextInt();

s1.close();

}

}

ERRO:

Exception in thread “main” java.util.NoSuchElementException
at java.util.Scanner.throwFor(Scanner.java:862)
at java.util.Scanner.next(Scanner.java:1485)
at java.util.Scanner.nextInt(Scanner.java:2117)
at java.util.Scanner.nextInt(Scanner.java:2076)
at scanner.AgCc(scanner.java:20)
at scanner.main(scanner.java:13)

Não há nenhum construtor declarado na sua classe.
Você só criou um método estático e dois atributos estáticos.
Algum motivo para ser tudo estático?

Seu objeto Scanner utiliza o System.in, mas acontece que ao final do método você está chamando o método close() do Scanner, que por consequência vai fechar o System.in.

Então após executar uma vez seu método AgCc() o System.in estará fechado e o Scanner não conseguirá ler nada dele.

Retire a chamada ao close() que vai resolver.

Dicas:

  • Nomes de classes devem ser substantivos;
  • Nomes de classes devem iniciar em maiúsculo;
  • Nomes de classes devem ser verbos;
  • Nomes de métodos devem iniciar em minúsculo;

Obrigado staroski, realmente retirando a chamada close funciona, mas ai ficam algumas duvidas.

Estou dando uma estudada com o livro do Peter Jandl Junior e ele fala que seria importante sempre fechar os objetos Scanner com close.

Eu chamo o método duas vezes, ele não deveria fechar e abrir novamente?

Originalmente o código estava escrito com dois métodos, um capturando agencia e o outro capturando conta, depois simplifiquei para coloca-lo aqui.

No exemplo abaixo ele dá o mesmo erro quando chama o método cc() da primeira vez e só funciona quando retiro a chamada ao close de ambos, mesmo sendo duas chamadas distintas. Inclusive o Eclipse dá o alerta de que não foi fechado com close quando eu os retiro.

import java.util.Scanner;

public class scanner {

private static int agenciaM ;

private static int ccM ;

public static void main(String[] args) {

ag ();

cc ();

System. out .println("Agencia / Conta: " + agenciaM + " / " + ccM );

ag ();

cc ();

System. out .println("Agencia / Conta: " + agenciaM + " / " + ccM );

}

public static void ag() {

Scanner s2 = new Scanner(System. in );

System. out .println("Digite o numero da agencia: ");

agenciaM = s2.nextInt();

s2.close();

}

public static void cc() {

Scanner s3 = new Scanner(System. in );

System. out .println("Digite o numero da agencia: ");

agenciaM = s3.nextInt();

s3.close();

}

O InputStream que você passou como parâmetro para o Scanner foi o System.in.
Não faz sentido fechar o System.in.

1 curtida

Entendi o problema!!

Faz sentido eu fechar um arquivo ou outra coisa, mas não o system.in.

Obrigado!