【问题标题】:Better options than util.Scanner to get and return user input in JAVA [duplicate]在 JAVA 中获取和返回用户输入比 util.Scanner 更好的选择 [重复]
【发布时间】:2018-09-24 17:37:40
【问题描述】:

感谢这里的一些反馈,我花了一些时间研究 util.Scanner。在How to use java.util.Scanner to correctly... 的这篇帖子中找到了最让我印象深刻的声明

您可能永远不会真正看到在专业/商业业务线应用程序中使用 Scanner,因为它所做的一切都被其他东西做得更好。现实世界的软件必须比 Scanner 让您编写代码更具弹性和可维护性。现实世界的软件使用标准化的文件格式解析器和文档化的文件格式,而不是您在独立作业中获得的即席输入格式。

因此,我查找了其他一些获取用户输入的选项,并决定使用 BufferedReader。我想要完成的是让用户告诉程序他们是否想继续玩游戏,让程序重复问题直到给出有效输入(Y/N),并让程序作为回答的结果继续或终止。

三个相关问题:

BufferedReader 是不是比 Scanner 更好的选择?

是否有更好地解决此任务的选项?如果是这样,它是什么?

如果答案不符合标准,让方法调用自身创建“循环”是否合适?

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class RageGame {

public static void main(String[] args) throws IOException  {

    char playAgain = 'Y';

    // Loop game until user decides they are done.
    do { 
        playAgain = playRage();

    } while (playAgain == 'Y');

    //Quit message      
    System.out.println("Thanks for playing Rage!");

}

public static char playRage() throws IOException {

    return playAgain();
}
public static char playAgain() throws IOException{
    char answer;

    BufferedReader kb = new BufferedReader(new InputStreamReader(System.in));

    //Ask the user if they want to continue and set their response to upper case.
    System.out.println("Do you wish to play again? (y/n)");
    answer = (char) Character.toUpperCase(kb.read());

    //Check if answer fits criteria
        if (answer != 'Y' && answer != 'N') {
            System.out.println("Sorry, " + answer + " is not a valid answer.");
            return playAgain();

        }else {
        return answer;


        }
    }
}

【问题讨论】:

  • 您不应该关闭使用 System.in 创建的扫描仪,因为它会关闭 System.in,而您并没有打开它。规则是,你应该关闭你打开的所有东西,但你打开的东西。
  • 使用try with resources 块。
  • 我还建议你遵循 Java 命名约定:类名总是以大写开头。
  • @DavidConrad 明白了!我最初在研究 Resource not closed 错误时看到了这个答案,但并没有真正理解它。我想这是因为我只看到了如何使用 System.in 创建扫描仪。我将对如何创建扫描仪进行更多研究。谢谢!

标签: java java.util.scanner bufferedreader


【解决方案1】:

简短的回答是:不要关闭它。

您的Scanner 正在使用流System.inSystem.in 不是你的程序获取的资源(你没有打开流),所以不应该关闭它。其他人负责关闭它。

如果您发现警告令人讨厌,您可以将其静音。

假设您的扫描仪从文件而不是System.in 获取输入,那么您需要在最后一次需要它之后调用close

answer = Character.toUpperCase(kb.next().charAt(0)); 
kb.close();

如果您害怕忘记拨打close,只需使用try-with-resources 块,它会为您关闭它!

try (Scanner kb = new Scanner(some other source)) {
    System.out.println("Do you wish to play again? (y/n)");
    answer = Character.toUpperCase(kb.next().charAt(0)); 
} // this will always close the scanner

【讨论】:

  • 在后一种情况下,try-with-resources 块是个好主意。
  • @DavidConrad 已编辑。
  • 太棒了!感谢@Sweeper 和@DavidConrad 的帮助!
【解决方案2】:

另外,如果您想关闭扫描仪,可以将System.in 包裹在CloseShieldInputStream 中。您的扫描仪将使用 代理流。有兴趣的可以看看http://commons.apache.org/proper/commons-io/apidocs/org/apache/commons/io/input/CloseShieldInputStream.html

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-04-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-16
    • 1970-01-01
    • 2020-05-24
    相关资源
    最近更新 更多