Scanner - NoSuchElementException

gta008

Mitglied
Guten Abend,

ich sitze nun seit vielen Stunden an einem Programm und komme nicht weiter. Ich bin jetzt soweit, das ich glaube die Fehlerstelle gefunden zu haben. Leider finde ich keine Lösung diesen Fehler zu beheben.
Das Programm soll ein Programm zum Karteikarten lernen sein - spielt aber für den Fehler keine Rolle. Um Folgenden Code geht es:
[CODE lang="java" title="learn Methode"]public void learn() {
String input = "";
for (int i = 0; i < number; ++i) {
System.out.println("Vorderseite: " + this.deck.getFront());
System.out.print("Was steht auf der Rueckseite? (Gross- und Kleinschreibung beachten): ");
Scanner scan = new Scanner (System.in);
try {
input = scan.next();
}catch (NoSuchElementException e) {
System.out.println("FEHLER!");
System.exit(0);
}
scan.close();
System.out.println(input);
}
}[/CODE]

Beim Ausführen dieser Methode geht Java immer in die Exception NoSuchElementException und beendet sich. Wieso geht er in diese Exception? Ich möchte, dass ich nach dem der Outprint "Was steht auf der Rueckseite? (Gross- und Kleinschreibung beachten): " erfolgt ist die Lösung eingeben kann. Was habe ich hier falsch gemacht?

Vielen Dank im Voraus.
 

temi

Top Contributor
Also erst mal solltest du nicht innerhalb der Schleife ständig neue Instanzen von Scanner erzeugen. Eine (vor der Schleife) reicht vollkommen, die kann man wieder verwenden.

Dann solltest du Scanner nicht schließen. Damit wird auch der InputStream von System.in (endgültig) geschlossen. Nur Resourcen die von dir geöffnet und verwaltet werden, sollten auch von dir geschlossen werden.
 

mihe7

Top Contributor
Der Hauptfehler besteht darin, dass Du den Scanner schließt.

Beim Schließen des Scanners wird auch der verwendete Stream geschlossen, hier also System.in. Daher wird jede weitere Verwendung von System.in zu einer Exception führen.
 

gta008

Mitglied
Leider folgt immer noch die selbe Fehlermeldung bei der Ausführung der Methode (ich habe try - catch jetzt entfernt, sodass die "normale" Fehlermeldung und nicht die eigene kommt), obwohl ich das close geschlossen habe. Ich werde nicht nach einer Eingabe gefragt.

[CODE lang="java" title="learn Methode"]public void learn() {
String input = "";
Scanner scan = new Scanner (System.in);
for (int i = 0; i < number; ++i) {
System.out.println("Vorderseite: " + this.deck.getFront());
System.out.print("Was steht auf der Rueckseite? (Gross- und Kleinschreibung beachten): ");
input = scan.next();
System.out.println(input);
}
}[/CODE]

Fehlermeldung in der Main Methode:

Vorderseite: Auge
Was steht auf der Rueckseite? (Gross- und Kleinschreibung beachten): Exception in thread "main" java.util.NoSuchElementException
at java.util.Scanner.throwFor(Scanner.java:862)
at java.util.Scanner.next(Scanner.java:1371)
at vocabtrainer.cards.CardDeck.learn(CardDeck.java:89)
at VocabTrainer.load(VocabTrainer.java:55)
at VocabTrainer.main(VocabTrainer.java:71)
 

LimDul

Top Contributor
Hast irgendwo anders noch einen Scanner, den du schließt im gesamten Programm?

Edit: Kann nicht die Ursache sein - dann würde eine andere Exception fliegen

Edit 2: Doch wird, die Ursache sein:

Java:
package de.limdul.javaforum;

import java.util.Scanner;

public class ScannerTest {

	public static void main(String[] args) {
		Scanner s1 = new Scanner(System.in);
		Scanner s2 = new Scanner(System.in);
		s1.close();
		s2.next();
	}
}

Ergebnis:
Exception in thread "main" java.util.NoSuchElementException
at java.base/java.util.Scanner.throwFor(Scanner.java:937)
at java.base/java.util.Scanner.next(Scanner.java:1478)
at de.limdul.javaforum.ScannerTest.main(ScannerTest.java:11)

=> Check dein ganzes Programm, dass du nie einen Scanner schließt
 

gta008

Mitglied
Hast irgendwo anders noch einen Scanner, den du schließt im gesamten Programm?
Du hast Recht, in der Methode in der ich die Methode learn aufgerufen habe, hatte ich noch einen Scanner kurz vorher geschlossen. Jetzt funktioniert das ganze, vielen Dank. Nur nochmal zum Verständnis, reicht es also, ganz am Anfang eines Programms einen Scanner zu starten, auch wenn sich das Programm über viele Methoden und Klassen zieht? Ich dachte nämlich, dass der geschlossene Scanner der Methode, mit der ich learn aufrufe, keinen Einfluss darauf hat, da ich ja in der Methode learn einen neuen Scanner erstellt habe.
 

LimDul

Top Contributor
Du schließt nicht nur den Scanner - sondern wie @mihe7 schon geschrieben hat, auch den darunterliegenden Stream, also die Konsoleneingabe.

Faustregel: Nur das schließen, was man auch aufgemacht hat. Und den Scanner machst du nicht auf, sondern setzt ihn auf einen bereits bestehenden Stream.
 

Neue Themen


Oben