• Scanner类throwFor(Unknown Source)及跳过下一个扫描器分析


    在使用Scanner类时遇到一个问题:

    1 Exception in thread "main" java.util.NoSuchElementException
    2     at java.util.Scanner.throwFor(Unknown Source)
    3     at java.util.Scanner.next(Unknown Source)

    在执行scanner.next()时遇到异常。Stack Overflow上给出了问题原因与解决办法。

    原因:当一个类中两个及两个以上的Scanner实例时,其中一个Scanner类的实例执行scanner.close()方法会关闭其他潜在的InputStream流,导致其他Scanner的扫描器无法读取输入流。

    解决办法:对于控制台程序,在程序运行中只注册一个Scanner类的实例从System.in中读取信息。

    问题二:使用Scanner#nextInt()时跳过下一个扫描器。

    产生原因:在使用Scanner#nextInt()时,nextInt()在遇到 ' '之前结束,但“ "会被下一个扫描器所接收,如Scanner#nextLine(),从而直接跳过Scanner#nextLine()。

    解决办法:统一使用Scanner#nextLine()代替所有扫描函数。然后进行强制类型转换。

    1 String nextIntString = keyboard.nextLine(); //get the number as a single line
    2 int nextInt = Integer.parseInt(nextIntString); //convert the string to an int

    补充:在使用Scanner#hasNextInt(),hasNextDouble()...函数时,如果返回值为false则应该在else语句中增加Scanner#nextLine()以抵消 ' '。

     1 public void showMenu() {
     2         System.out.println("****************************");
     3         System.out.println("Option Menu");
     4         System.out.println("1、登录");
     5         System.out.println("2、注册");
     6         System.out.println("3、退出");
     7         System.out.println("请选择:");
     8         System.out.println("****************************");
     9         if (scanner.hasNextInt()) {
    10             int index = Integer.parseInt(scanner.nextLine());
    11             choice(index);
    12         } else {
    13             scanner.nextLine();
    14             System.out.println("请输入数字...");
    15             showMenu();
    16         }
    17     }

    问题一解释

    You close the second Scanner which closes the underlying InputStream, therefore the first Scanner can no longer read from the same InputStream and a NoSuchElementException results.

    The solution: For console apps, use a single Scanner to read from System.in.

    Aside: As stated already, be aware that Scanner#nextInt does not consume newline characters. Ensure that these are consumed before attempting to call nextLine again by using Scanner#newLine().

    问题二解释:

    The nextInt() method leaves the (end line) symbol and is picked up immediately by nextLine(), skipping over the next input. What you want to do is use nextLine() for everything, and parse it later:

    String nextIntString = keyboard.nextLine(); //get the number as a single line
    int nextInt = Integer.parseInt(nextIntString); //convert the string to an int
    

    This is by far the easiest way to avoid problems--don't mix your "next" methods. Use only nextLine() and then parse ints or separate words afterwards.


    Also, make sure you use only one Scanner if your are only using one terminal for input. That could be another reason for the exception.


    Last note: compare a String with the .equals() function, not the == operator.

    if (playAgain == "yes"); // Causes problems
    if (playAgain.equals("yes")); // Works every time
    
  • 相关阅读:
    获取时间对象
    定时器
    undefined与return
    获取设置非行间样式
    NaN
    return,break与continue的区别
    数据类型
    程序的机器级表示
    计算机内数字的表示
    计算机系统漫游
  • 原文地址:https://www.cnblogs.com/mada0/p/4694126.html
Copyright © 2020-2023  润新知