当前位置: 首页 > 知识库问答 >
问题:

如何关闭扫描仪对象时,输入是在一个循环?

周浩淼
2023-03-14

我使用while循环从控制台获取输入并调用我的输入()方法。但是当我尝试关闭扫描仪对象时,它会出现运行时错误。当对象未关闭时,程序正确运行,但eclipse发出警告,资源泄漏:'s'永远不会关闭。如何修复它?我的输入代码是

    String input()
    {
        try
        {
            Scanner s = new Scanner(System.in);
            String str=s.nextLine();
            s.close(); // error because of this 
            return str; 
        }

public class validation  {
    public static void main(String args[])
    {
    try
        {
            String name;
            String email_id;
            String number;
            validation v= new validation();
            do{
            System.out.println("Enter the name");
            name=v.input();
            }
            while (!(v.validate_name(name)) );

            do{
                System.out.println("Enter valid Mobile Number");
                number=v.input();
            }
            while(!(v.validate_number(Long.parseLong(number))) || !(v.filevalidate(number)));

            do{
            System.out.println("Enter valid Email_id");
            email_id=v.input();
            }
            while(!(v.validate_email(email_id)) || !(v.filevalidate(email_id)));

            v.writeToFile(name,number,email_id);
        }       
        catch(Exception e){System.out.println(e);}

错误输出为

输入姓名Justin输入有效的移动电话号码java。util。NoSuchElementException:找不到java行。lang.NumberFormatException:null

共有2个答案

孔俊友
2023-03-14
String input(){
    Scanner s = null;
    try {
        s = new Scanner(System.in);
        //your code
    }
    finally {
        if(s!=null)
            s.close();
    }
    }

像这样尝试并评论您的回应!希望它能正常工作。我可以看看你的filevalidate和validate\u number方法吗!

魏彦
2023-03-14

关闭Scanner对象会导致它也关闭其关联的InputStream或文件。如果您要在输入()方法中使用Scanner从文件而不是从键盘读取数据,您可以这样使用它:

String input() {
    InputStream is = new FileInputStream(INPUT_FILE_NAME);
    Scanner s = new Scanner(is);
    String str = s.nextLine();
    s.close();
    return str;
}

如您所见,扫描仪已关闭,因此没有资源泄漏。如果不关闭它,在文件上打开的InputStream将保持打开状态。仅关闭扫描仪也会关闭构建扫描仪的输入流。因此,也不需要关闭InputStream。

上面的代码相当于下面的代码,但下面的代码更安全,因为它正确地处理异常:

String input() {
    try (
        InputStream is = new FileInputStream(INPUT_FILE_NAME);
        Scanner s = new Scanner(is)
    ) {
        String str = s.nextLine();
        return str;
    }
}

这是try-with-Resources语句,您可以在Oracle的网站或一本好的教科书上阅读。它确保在方法返回之前始终关闭InputStream和Scanner,无论发生什么。

那么,为什么我们不应该对系统上打开的扫描仪执行同样的操作呢。是否在?这是因为系统。在中是一个输入流,我们希望它在整个程序期间保持打开状态。如果我们关闭扫描仪,也会关闭系统。我们不希望这样。但是现在我们没有关闭扫描仪,我们不想每次输入input()方法时都创建一个新的扫描仪。我们只想创建一个扫描程序,它可以持续整个程序。一种方法是将其作为字段:

public class Validation {
    private static Scanner in = new Scanner(System.in);

    String input() {
        return in.nextLine();
    }

    ...
}

现在,一旦JVM加载了您的类,就会创建扫描程序,并在程序退出之前保持可用状态。

我不确定如果您将Scanner对象构造为静态字段(我不使用Eclipse),Eclipse是否仍会抱怨资源泄漏。也许您可以让我知道它是否存在。

 类似资料:
  • 我开发了一个字符排序器,我想每次字符串排序后提示用户输入一个新的字符串。我遇到的问题是扫描仪一直在扫描用户的第一个输入。如果我使用scanner.next(),它不会计算输入末尾的空白,这不是解决方案。 这是while循环的开始。一旦代码完成,它将再次从“inputtext”开始。

  • 在分离标记之前,我试图检查扫描仪是否有多个标记。我目前正在尝试使用扫描仪。hasNext()(我的扫描仪的名字是sc)。如果用户输入“string int”,那么我不想打印“enter age”或“enter grade” 目前,无论输入是什么,我的程序都会跳过if语句。如果我把它拿走!然后,即使输入是一行,这些行也会打印出来。他们似乎也打印后,下一个是我发现奇怪的。我将非常感谢您的帮助!

  • 问题内容: 我试图将我的应用程序中较大且经常使用的部分重构为单独的方法,以使其易于维护。 其中一些方法要求用户输入并进行输入验证,因此我使用了Scanner和System.in,但是当我关闭Scanner时,我也关闭了System.in。 所以我的问题是,我只能通过用CloseShieldInputStream屏蔽System.in来防止System.in关闭,还是应该开始将Scanner传递给方

  • 我试图将应用程序中大量且经常使用的部分重新划分为不同的方法,以使其更容易维护。 其中一些方法要求用户输入并进行输入验证,因此我使用了扫描仪和系统。但当我关闭扫描仪时,我也会关闭系统。在里面 所以我的问题是,我只能阻止系统。通过使用CloseShieldInputStream屏蔽它来关闭,还是我应该开始向方法传递一个扫描器?

  • 问题内容: 我正在尝试做的是拥有多个具有不同变量的输入。每个变量将是不同方程式的一部分。我正在寻找一种方法来做,我想我有一个主意。我只想知道这是否合法,也许还有更好的方法。 问题答案: 如果每个输入都问相同的问题,则应使用循环和输入数组: 或者如Chip所建议的,您可以从一行中解析输入: 您在正确的轨道上,所做的工作正常。这只是一种更好,更灵活的处理方式。