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

一个扫描器应该只实例化一次吗?如果是这样,为什么会这样?

慕容念
2023-03-14

我知道我在这里有点手足无措,但我似乎不明白为什么我们不能创建两次Scanner类的实例。我将添加一个示例以防万一。

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();
        
    }
}

我会得到一个运行时错误,如下所示

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)

我知道再次创建同一个类的新对象是没有意义的,鼓励冗余。但我只是觉得如果我知道为什么会让我头脑清醒,你不是也这么认为吗?

机器所说的“java.util.NosuchelementException:No line found”是什么意思,人们说扫描器是不可克隆的。

PS:我故意关闭了我的第一个扫描仪,创建了一个新的对象,只是为了理解这个问题。

共有1个答案

慕容博涛
2023-03-14

实际上这里发生了两件事情。

>

  • 您应该为每个输入源创建一个扫描器。例如,每个不同的输入文件使用一个scannersystem.in,每个不同的套接字输入流使用一个scanner

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

    这就是为什么在system.in上打开多个scanner对象是糟糕的真正原因。而不是你提出的“冗余”论点。有一点冗余从根本上来说没有什么问题...特别是如果它简化了应用程序的话。但扫描器竞争输入可能会导致意外的行为/错误。

    第二个问题是,当您close()同时关闭输入源的扫描器

    在您的情况下,这意味着您正在关闭system.In。然后创建第二个扫描器以从(现在关闭的)System.in读取。

    当您尝试使用扫描器从关闭的系统中读取时,这将导致NosuchelementException

    因此,如果您没有在第一个扫描器上调用close(),您的代码可能可以工作,但这取决于您在第一个扫描器上所做的操作顺序。

    人们说scanner是不可克隆的。

    他们是正确的。

  •  类似资料:
    • 使用自定义比较器,每次实例化比较器,而不是将其创建为常量(使用匿名类)并使用单个实例,有什么好处吗?我一直认为每次创建一个新实例没有什么好处,并且一直采用选项2(静态final字段中的单个实例)。 这里的假设是没有状态需要保留在比较器中。 如果do某物()被称为很多呢?如果do某物()从多个线程被调用怎么办?如果CUSTOM_COMPARATOR被拉到一个普通的班级里,公开而不是私下呢?

    • 我发现这样的php代码: 我希望这个循环会执行4次,因为$I变成了对$的引用(对吗?)。然而,循环只执行一次,并输出: a=10,i=10 我不明白为什么它会这样工作。有什么想法吗?

    • 我正在看宣传单。 在setTimeout中调用

    • 我知道类和抽象类的主要区别是,抽象类不能被实例化, 但是我可以为抽象类创建对象 我用新的关键字创建了抽象的对象 我有一些问题在 Inet 上没有正确的答案, new关键字是否用于实例类? 2)实例只不过是对象吗? 3)mEarth被称为物体(地球的实例)吗? 现在我可以调用任何方法(作为回调或作为值返回)mearth . sand();mearth . land();使用地球物体

    • 我试图让程序允许用户输入一个数字,然后让计算机告诉用户这个数字是否太小、太大或等于随机生成的数字。提示和输入有效,但在第一次扫描后就卡住了。 我认为这与scanf有关,而不是与条件有关,因为我添加了printf(“测试停止点”),但它不会打印到用户屏幕上。我做错了什么?

    • 本文向大家介绍RSA会受到攻击吗?如果是这样,怎么办?相关面试题,主要包含被问及RSA会受到攻击吗?如果是这样,怎么办?时的应答技巧和注意事项,需要的朋友参考一下 回答:**是的,黑客可以攻击RSA算法。但是,受到攻击并不等于薄弱的保护。 通常,有两种攻击RSA的方法: 蛮力:包括所有潜在的秘密密钥。 数学攻击:在这种情况下,我们使用不同的技术来近似地计算两个素数的乘积。