扫描程序应该只实例化一次吗?如果是这样的话,为什么呢? [英] Should a Scanner only be instantiated only once? if that's the case why so?

查看:104
本文介绍了扫描程序应该只实例化一次吗?如果是这样的话,为什么呢?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道我要为此付出努力,但是我似乎无法理解为什么我们不能两次创建Scanner类的实例.为了防万一,我将添加一个示例.

I know I'm going out on a limb here, but I just can't seem to understand why can't we just create an instance of the Scanner class twice. I'll add an example just in case.

import java.util.Scanner;

public class Nope
{
    public static void main(String[] args)
    {
        System.out.println("What's your name?");
        Scanner scanner = new Scanner(System.in);
        String name = scanner.nextLine();
        
        System.out.println("Welcome " + name + "!");
        scanner.close();
        
        // Now 
        System.out.println("where you do live?");
        Scanner sc = new Scanner(System.in);
        String country = sc.nextLine();
        
        System.out.println("That's a lovely place");
        sc.close();
        
    }
}

然后我收到一个运行时错误,看起来像这样

And I get a runtime error which looks something like this

What's your name?
Kate
Welcome Kate!
Exception in thread "main" where you do live?
java.util.NoSuchElementException: No line found
    at java.base/java.util.Scanner.nextLine(Scanner.java:1651)
    at Nope.main(Nope.java:17)

我知道再次创建相同类的新对象没有意义,这会鼓励冗余.但是我只是认为,如果我知道为什么会打扫我的头脑,你不是也这么认为吗?

I know it doesn't make sense to create a new object again of the same class, encouraging redundancy. But I just think it will clear my mind if I know why, don't you think so too?

"java.util.NoSuchElementException:找不到行"是什么意思?,人们说Scanner不可克隆.

What does the machine mean by 'java.util.NoSuchElementException: No line found' and people are saying Scanner ain't cloneable.

PS:我故意关闭了第一台扫描仪并创建了一个新对象,目的只是为了了解问题.

PS: I intentionally closed my first scanner and created a new object just to understand the issue.

推荐答案

这里实际上有两件事.

  1. 您应为每个输入创建一个Scanner.例如,对于每个不同的输入文件一个Scanner,对于System.in一个,对于每个不同的套接字输入流一个.

  1. You should create one Scanner per input source. For example, one Scanner for each distinct input file, one for System.in, one for each distinct socket input stream.

原因是(正如Chrylis所指出的)Scanner的各种方法是在扫描仪的输入源上预先读取的.如果操作未消耗字符,则不会将其放回输入源.相反,它们由Scanner缓冲,并保留以供下一个Scanner操作使用.因此,如果您有两个扫描仪试图从相同的输入源读取,则其中一个可能会窃取用于另一个输入.

The reason is (as Chrylis points out) is that various methods of Scanner read ahead on the scanner's input source. If the characters are not consumed by the operation, they are not put back into the input source. Rather they are buffered by the Scanner, and kept for the next Scanner operation to use. So if you have two Scanners trying to read from the same input source, one may steal input intended for the other.

这是实际的原因,为什么在System.in上打开多个Scanner对象很糟糕.不是冗余",而是冗余".你提出的论点.一点冗余从根本上是没有错的……尤其是在简化应用程序的情况下.但是扫描程序争夺输入 可能会导致意外的行为/错误.

This is the real reason why opening multiple Scanner objects on System.in is bad. Not the "redundancy" argument that you proposed. There is nothing fundamentally wrong with a bit of redundancy ... especially if it simplifies the application. But scanners competing for input may result in unexpected behavior / bugs.

第二个问题是,当您close()一个Scanner时也会关闭输入源.

The second problem is that when you close() a Scanner that also closes the input source.

在您的情况下,这意味着您要关闭System.in.然后,您将创建第二个Scanner以便从(现已关闭的)System.in中读取.

In your case that means that you are closing System.in. And then you are creating a second Scanner to read from the (now closed) System.in.

当您尝试给我们Scanner从封闭的System.in中读取时,会导致NoSuchElementException.

When you attempt to us a Scanner to read from a closed System.in, that leads to a NoSuchElementException.

因此,如果您没有在第一个Scanner上调用close(),则您的代码可能起作用了,但这取决于您对第一个Scanner进行的操作顺序.

So if you hadn't called close() on the first Scanner, your code might have worked, but that would depend on the sequence of operations you made on the first Scanner.

人们说Scanner不可克隆.

他们是正确的.

这篇关于扫描程序应该只实例化一次吗?如果是这样的话,为什么呢?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆