导致永恒循环迭代的扫描器对象

问题描述 投票:0回答:1

我在 while 循环中遇到 Scanner 问题。

每当我有一个 while (true) 循环从扫描仪读取数据时,只要我关闭扫描仪对象,while 循环就会开始无限循环,以为我关闭了流。但是我在一个单独的方法中打开和关闭流,正如我想象的那样,每次调用该方法时都应该打开和关闭它,但事实并非如此。 目前有用的是在循环外创建 Scanner 对象并将其作为参数发送给方法,再加上添加 scannerObject.next() 方法。

我不想改变循环条件。有没有正常的方法来避免这个错误?

import java.util.Scanner;

public class Main {

    public static void main(String[] args) {
        //testing how to have a while loop that only stops if q is entered
        Scanner userInput = new Scanner(System.in);
        
        while(true) {               
            int number = input(userInput);
            
            switch(number) {
                
            case 0: // returns 0 for Invalid input
                System.out.println("Invalid input. Enter an integer or q to Quit");
                break;
                
            case -1: // returns 1 to quit the program
                //
                System.out.println("You chose to quit. Good-bye");
                System.exit(0);
                break;
                
            default: // default is done when the input returns an integer, so valid input
                System.out.println("You entered " + number);
                break;
            }                   
            //System.out.println("I am now after the while loop");
        }// end of while(true) loop for userinput
        
    }

    private static int input(Scanner userInput) {
        System.out.println("Enter an integer or q to Quit the program: ");                  
        int result = 0;         
        if(userInput.hasNextInt()) {
            result = userInput.nextInt();               
        }           
        else {              
            if(userInput.hasNext("q")) {                    
                result = -1;
            }
            else {
                
                userInput.next();
//              result = 0;
            }
        }           
        return result;          
    }
}

java java.util.scanner
1个回答
0
投票

关闭
Scanner
关闭其基础
System.in

引用 Javadoc

Scanner#close

如果这个扫描器还没有关闭,那么如果它的底层可读对象也实现了

Closeable
接口那么可读对象的关闭方法将被调用。

System.in
对象是一个
InputStream
。并且
InputStream
确实实现了
Closeable
。所以传递关闭确实适用。

所以……关闭一个基于

Scanner
对象的
System.in
对象会同时关闭两个对象。

System.in
无法重开

不要那样做,不要关闭

System.in
。你不能重新打开
System.in
.

通常,您应该关闭诸如

Scanner
之类的资源。
Scanner
类甚至是
AutoCloseable
使用 try-with-resources 语法使这种关闭变得容易。

但是如果您的扫描器是基于

System.in
,那么我们有一个例外always-close-your-resources规则。

详情请见:

© www.soinside.com 2019 - 2024. All rights reserved.