Método nextLine da classe Scanner não funciona (não solicita o dado)

Por que o método nextLine não funciona? O nextByte funciona, mas o nextLine não. O interessante é que quando ignoro o nextByte (comento “//”), o nextLine captura a informação.

import java.util.Scanner;

public class Exercicio0605{
	
	public static void main (String[] args){

		Scanner scan = new Scanner(System.in);

		System.out.print("\nInforme um número inteiro: ");
		byte num = scan.nextByte();
		
		System.out.print("O número é maior que zero? ");
		String resposta = scan.nextLine();

		System.out.print("A sua resposta é: " 
                 + (num > 0 && resposta == "Sim" ? "Verdadeira" : "Falsa"));

	}

}

Você invoca o método nextByte() antes.
Sempre que você invocar qualquer método next, você vai acabar deixando “lixo” no stream de entrada.
É este lixo que é lido.

Exemplo:

Vamos supor que você precise ler idade e nome de uma pessoa.

System.out.println(“Idade”);
int idade = sc.nextInt();//Usuário digita 45 e pressiona enter que é lido como \n
System.out.println(“Nome”);
String nome = sc.nextLine();//Não espera digitar e pula para a próxima linha

O código acima exemplifica o que acontece. Quando você invoca o nextInt() (ou nextFloat() ou nextDouble() ou nextByte() ou nextLong(), etc), lê apenas a parte que vem antes do “\n”, que é o sinal que o Scanner espera para capturar o valor que lhe cabe.
Neste cenário, o valor inteiro (ou byte, ou float, ou long ou double, etc) é lido sem problemas.
Porém, esta leitura só retira do stream a parte numérica, deixando o \n lá.
Quando o método nextLine() é invocado, o mesmo encontra um “\n” lá dando bobeira, o captura e não se comporta como esperado.

Assim sendo, a única forma de resolver o problema é sempre utilizar o método nextLine().
Ok, ele só lê Strings!
Aí entram as classes wrappers, que são classes que representam os oito tipos primitivos do java

boolean -> Boolean
byte    -> Byte
short   -> Short
int     -> Integer
char    -> Character
float   -> Float
long    -> Long
double  -> Double

Cada qual possui métodos responsáveis por transformar uma String em um tipo primitivo correspondente ou um objeto daquela classe.

Exemplo:

System.out.println("Idade");
String sIdade = sc.nextLine();//O usuário digita 45 e pressiona a tecla enter, \n
int idade = Integer.valueOf(sIdade);//pega a parte inteira e transforma no int

Entendeu?

1 curtida

Olá,
Eu me deparei com o mesmo problema, mas achei uma resposta diferente no site https://www.devmedia.com.br/entrada-de-dados-classe-scanner/21366

Aqui explica que só precisamos colocar um scan.nextLine(); (no seu caso) antes da próxima leitura. Assim da tudo certo.

@C4sh3w olá, a solução para isso é você colocar mais um nextline,exemplo

System.out.print("\nInforme um número inteiro: ");
byte num = scan.nextByte();

scan.nextLine();//aqui

System.out.print("O número é maior que zero? ");
String resposta = scan.nextLine();

aqui tá a explicação:

A explicação não é diferente. Se você leu tudo o que foi escrito acima, verá que ele coloca que o nextInt não lê o “\n”.
A função desse “nextLine()” após ler o dado é, justamente, consumir essa quebra que ficou esquecida.
Assim, o próximo dado inserio pelo usuário pode ser lido sem problemas.
A questão é: quantos dados serão lidos? É viável encher o código de “nextLine()”? Ou é preferível usar os wrappers e empacotar as informações, sem tanta repetição?

@darlan_machado Eu penso exatamente igual a você, mas o código no qual eu estava trabalhando era pequeno e optei por colocar nextLine, mas concordo que um código maior merece sim uma atenção, e empacotar as informações seria melhor. Mas só compartilhei como uma outra opção também. ^^

Acredito que a questão vá um pouco além, @Matheus_Cordeiro. Quantos sistemas, efetivos e de uso comercial, se constroem dessa maneira, ainda?