Input/Output NoSuchElementException

sB6

Mitglied
Mein Programm soll mittels Scanner-Klasse eine natürliche Zahl über die Konsole einlesen, welche kleiner als 8 sein soll.
Falls ein String eingegeben wird, soll die (eigens erstellte Exception-Klasse) "ExceptionKlasse_keinInteger" geschmissen werden.
Falls eine Zahl größer 7 eingegeben wird, soll die (eigens erstellte Exception-Klasse) "ExceptionKlasse_groesser7" geschmissen werden.
Das Programm wird in der main-Methode gestartet und soll solange mittels while-Schleife durchlaufen werden, bis über die Konsole eine Zahl kleiner 8 eingegeben wurde.
Java:
import java.util.InputMismatchException;
import java.util.Scanner;

public class Rechner {
   
    public static void methode() throws ExceptionKlasse_groesser7, ExceptionKlasse_keinInteger {
        System.out.println("Bitte eine natürliche Zahl kleiner 8 eigeben: ");
       
        int x;
        try {  
           
            Scanner scanner = new Scanner(System.in);
            x = scanner.nextInt();
            scanner.close();
        }
        catch(InputMismatchException c) {
            throw new ExceptionKlasse_keinInteger();
        }
        if(x>7) {
            throw new ExceptionKlasse_groesser7();
        }
       
        System.out.println("Eingegebene Zahl: " + x);
    }
   
    public static void main(String[] args) {
        boolean schleifenvariable = true;
        while(schleifenvariable) {
            try {
                methode();
                schleifenvariable = false;
            }
            catch(ExceptionKlasse_keinInteger e) {
                System.out.println(e.getMessage());
            }
            catch(ExceptionKlasse_groesser7 b) {
                System.out.println(b.getMessage());
            }
        }
    }
}
Falls ich einen String eingebe wird das Programm ausgeführt so wie soll.
Falls ich eine Zahl kleiner 8 eingebe wird das Programm beendet, so wie es sein sollte:
1631558773349.png

Problem:
Falls eine Zahl größer 7 eingegeben wird, wird die gewollte Exception (ExceptionKlasse_groesser7) geschmissen und es wird auch ein Teil der Methode ausgeführt, aber ich erhalte immer die Fehlermeldung: "NoSuchElementException":
1631558869187.png


Wie kann ich dieses Problem lösen?
 
Zuletzt bearbeitet:

Barista

Top Contributor
Vor scanner.nextInt scanner.hasNextInt(); aufrufen.

Die Methode hasNextInt blockiert, deshalb kann man das boolean-Ergebnis ignorieren.
 
K

kneitzel

Gast
ich habe jedoch eine Lösung gefunden, indem ich einfach das "scanner.close" weglasse! ich verstehe aber nicht warum es jetzt aufeinmal funktioniert :D
Wenn Du den Scanner schliesst, dann schliesst du auch den Stream dahinter. Das bedeutet, dass Du System.in durch das Scanner.close() schliesst so dass danach keine weiteren Eingaben möglich sind.

An der Stelle dann auch der Hinweis, dass es eine sehr schlechte Praxis ist, immer einen neuen Scanner zu erstellen. Dadurch kannst Du in Situationen kommen, an der das Verhalten nicht vorhersagbar ist.

Dies liegt daran, dass Scanner einen internen Puffer hat, der Teile aus dem Stream einliest. Nehmen wir nun einfach einmal den Fall, dass Du die Eingabe für die Konsolenanwendung aus einer Datei nimmst (Also auf der Kommandozeile beim Start z.B. per angehängtem " < eingabe.txt")
Der erste Scanner liest nun einen Teil aus dem Eingabestrem ein. Von den Zeichen wird aber nur ein Teil ausgewertet (z.B. bei nextInt() eine Zahl). Aber es werden auch noch mehr Zeichen aus dem Stream gelesen und verbleiben im Puffer des Scanners.
Wenn Du nun einen neuen Scanner auf de, Stream erzeugst, dann liest der die nächsten Zeichen aus dem Stream, die Zeichen, die noch im Puffer des ersten Scanners sind, werden ignoriert.
 
K

kneitzel

Gast
also wäre es sinnvoller in meiner Klasse ein Klassenfeld Scanner zu erzeugen, auf welches ich dann immer zugreife?
Ja, das wäre der richtige Weg aus meiner Sicht.

Eine weitere Änderung wäre dann aber noch, dass du eine ungültige Eingabe aus dem Scanner entfernen musst. Dies wäre dann bei der InputMismatchException ein Aufruf von nextLine oder so.
 

sB6

Mitglied
Eine weitere Änderung wäre dann aber noch, dass du eine ungültige Eingabe aus dem Scanner entfernen musst. Dies wäre dann bei der InputMismatchException ein Aufruf von nextLine oder so.
,dass ist mir auch aufgefallen als ich es gemacht habe! :D
Habe aber die scanner.nextLine()-Anweisung in die MainMethode verpackt bei der ersten catch-Anweisung.
 

Ähnliche Java Themen

Neue Themen


Oben