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

Scanner object causing an eternal loop iteration

提问人:rainbow 提问时间:5/16/2023 更新时间:5/16/2023 访问量:48

问:

我在 while 循环中使用 Scanner 有问题。

每当我从扫描仪读取一段时间(真)循环时,一旦我关闭扫描仪对象,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.util.scanner

评论

0赞 maloomeister 5/16/2023
"。只要我关闭扫描仪对象......”- 不要关闭包装,因为它也会关闭底层流ScannerSystem.in
0赞 maloomeister 5/16/2023
这回答了你的问题吗?关闭链接到 System.in 的扫描仪
0赞 Basil Bourque 5/16/2023
此代码示例似乎与您的问题无关。您不会在该代码中的任何位置关闭扫描程序。

答:

1赞 Basil Bourque 5/16/2023 #1

平仓 平仓 其标的ScannerSystem.in

引用 Javadoc for Scanner#close

如果此扫描程序尚未关闭,则如果其基础可读对象也实现了 Closeable 接口,则将调用可读对象的关闭方法。

System.in 对象是 InputStream。并且确实实现了 Closeable。因此,传递闭合确实适用。InputStream

所以。。。基于对象关闭对象会同时关闭两者。ScannerSystem.in

System.in无法重新打开

不要那样做,不要关闭.您无法重新打开 。System.inSystem.in

通常,您应该关闭资源,例如 .该类甚至是 AutoCloseable,以便使用 try-with-resources 语法使这种关闭变得容易。ScannerScanner

但是,如果您的扫描程序基于 ,那么我们对 always-close-your-resources 规则有一个例外。System.in

有关详细信息,请参阅:

评论

0赞 rainbow 5/16/2023
但是在同一个方法中打开和关闭它,它不应该在每次新方法调用时通常重新打开吗?我不明白为什么流没有重新打开
1赞 Basil Bourque 5/16/2023
@rainbow 您无法重新打开 。System.in
0赞 rainbow 5/16/2023
不确定关闭是否是这里唯一的问题,因为在这个代码片段中我不关闭,但是一旦我删除了userInput.next();行它再次卡在循环中。
0赞 Basil Bourque 5/16/2023
@rainbow Your Question 说您用其他代码关闭了它,但您令人困惑地选择不向我们显示。
0赞 rainbow 5/16/2023
我的问题说有什么方法可以避免错误,因为我目前的出路是取出循环外的扫描仪对象并使用下一个方法,我不确定这是解决问题的最佳方法