java Scanner在新实例上没有使用nextLine的问题

时间:2014-02-11 18:32:10

标签: java java.util.scanner nosuchelementexception system.in

package sandbox2;

import java.util.Scanner;

public class Sandbox2
{
    public static void main(String[] args)
    {
        for (int i = 0; i < 5; i++)
        {
            String s = askForProperty("Enter value for " + i + ": ");
            System.out.println(i + " is: " + s);
        }

    }

    private static String askForProperty(String message)
    {
        Scanner keyboard = new Scanner(System.in);
        System.out.print(message);
        String s = keyboard.nextLine();
        keyboard.close();

        return s;
    }
}

当我运行上面的代码时,它会返回第一个PERFECTLY响应。当它试图请求第二个响应时,它返回:

java.util.NoSuchElementException: No line found

为什么会返回此错误?每次调用方法askForProperty时,Scanner都是一个全新的实例!它与System.in有什么关系作为输入流吗?

3 个答案:

答案 0 :(得分:0)

将扫描仪定义为类变量,然后仅在完成所有迭代后关闭它。在您当前的设置中,当您致电keyboard.close时,您也将关闭System.in,这会使其在以后无法使用。

package sandbox2;
import java.util.Scanner;

public class Sandbox2 {
    static Scanner keyboard = new Scanner(System.in); // One instance, available to all methods

    public static void main(String[] args)  {
        for (int i = 0; i < 5; i++) {
            String s = askForProperty("Enter value for " + i + ": ");
            System.out.println(i + " is: " + s);
        }
        keyboard.close(); //Only close after everything is done.
    }

    private static String askForProperty(String message) {
        System.out.print(message);
        String s = keyboard.nextLine();
        return s;
    }
}

答案 1 :(得分:0)

关闭Scanner会导致基础InputStream关闭。由于只有一个System.in,因此任何新创建的Scanner对象都无法从同一个流中读取:

keyboard.close();

关闭最后一个Scanner

答案 2 :(得分:0)

所以,

代码中的主要问题是您在每次迭代中立即创建并关闭Scanner。这根本行不通。想象一下Scanner作为与IO的大型连接,需要相当多的组合。如果你每次打开/关闭它 - 你可能只是找到一个情况,在再次打开连接之前触发下一个命令。它与数据库连接中的内容非常相似。防止它的方法是在开始迭代之前打开扫描仪,完成循环然后关闭它。

因此,从askForProperty()函数中删除close()语句并将其移动到main。将扫描仪键盘对象传递给该功能。一旦所有迭代结束 - 然后关闭它。

import java.util.Scanner;

public class Sandbox2
{
    public static void main(String[] args)
    {
        Scanner keyboard = new Scanner(System.in); // Initialize the Scanner
        for (int i = 0; i < 5; i++)
        {
            String s = askForProperty("Enter value for " + i + ": ", keyboard); // Pass the Scanner
            System.out.println(i + " is: " + s);
        }
        keyboard.close(); // Close the Scanner now that the work is done.
    }

    private static String askForProperty(String message, Scanner keyboard)
    {
        System.out.println(message);
        String s = keyboard.nextLine();
        return s;
    }
}