博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
scanner使用中遇见的问题
阅读量:5902 次
发布时间:2019-06-19

本文共 4242 字,大约阅读时间需要 14 分钟。

近期在学习的过程中遇见一个问题,问题不难但还是须要去认真对待。

先看看我写的源码

public static void main(String[] args){			for(;;){			Scanner in = new Scanner(System.in);			System.out.println("-----");			int age = in.nextInt();			System.out.println("------");			in.close();			System.out.println(age>100);		}		}
在这段代码中。当第一次输入是不会有错,能正常执行;然后第二次循环报错。

报出来的错误为:

Exception in thread "main" java.util.NoSuchElementException

at java.util.Scanner.throwFor(Scanner.java:838)
at java.util.Scanner.next(Scanner.java:1461)
at java.util.Scanner.nextInt(Scanner.java:2091)
at java.util.Scanner.nextInt(Scanner.java:2050)
at day01.Demo01.main(Demo01.java:11)

看到这,感觉到相当的郁闷。当我们把in.close()这段代码给凝视掉的话。那这段代码能够无限的循环下去。

可是从这段代码的逻辑来看,似乎没错,但机器给我们报出了错。这就须要我们去找到错误的。

依据报出来的错,我们看到是int age = in.nextInt();这行代码出错。

从这报出来的错误中来分析。简要的说,就是前后两次实例化的參数System.in是用一个对象,是InputStreamReader对象,每一个该对象包括一个StreamDecoder 实例 sd,private final StreamDecoder sd;  

而in.close()方法为

public void close() {          if (closed)              return;          if (source instanceof Closeable) {              try {                  ((Closeable)source).close();              } catch (IOException ioe) {                  lastException = ioe;              }          }          sourceClosed = true;          source = null;          closed = true;      }

当运行到 ((Closeable)source).close();就会进入InputStreamReader的close()方法:

public void close() throws IOException {                   sd.close();    }

这里的sd就是上面提到的InputStreamReader对象,(又查了StreamDecoder 源码,但没更深入下去),此时sd已关闭。

当运行如错误产生代码的第11行代码 in.nextInt()时。

public int nextInt(int radix) {        // Check cached result        if ((typeCache != null) && (typeCache instanceof Integer)	    && this.radix == radix) {            int val = ((Integer)typeCache).intValue();            useTypeCache();            return val;        }        setRadix(radix);        clearCaches();        // Search for next int        try {            String s = next(integerPattern());            if (matcher.group(SIMPLE_GROUP_INDEX) == null)                s = processIntegerToken(s);            return Integer.parseInt(s, radix);        } catch (NumberFormatException nfe) {            position = matcher.start(); // don't skip bad token            throw new InputMismatchException(nfe.getMessage());        }    }
当中调用了next()方法

public String next(Pattern pattern) {        ensureOpen();        if (pattern == null)            throw new NullPointerException();        // Did we already find this pattern?        if (hasNextPattern == pattern)            return getCachedResult();        clearCaches();        // Search for the pattern        while (true) {            String token = getCompleteTokenInBuffer(pattern);            if (token != null) {                matchValid = true;                skipped = false;                return token;            }            if (needInput)                readInput();            else                throwFor();        }    }

异常是从方法throwFor();中抛出,而异常的来源是readInput()方法

private void readInput() {           if (buf.limit() == buf.capacity())               makeSpace();            // Prepare to receive data           int p = buf.position();           buf.position(buf.limit());           buf.limit(buf.capacity());            int n = 0;           try {               n = source.read(buf);           } catch (IOException ioe) {               lastException = ioe;               n = -1;           }            if (n == -1) {               sourceClosed = true;               needInput = false;           }            if (n > 0)               needInput = false;            // Restore current position and limit for reading           buf.limit(buf.position());           buf.position(p);       }

当运行到12行source.read()时,source是Reader类

public int read(java.nio.CharBuffer target) throws IOException {       int len = target.remaining();       char[] cbuf = new char[len];       int n = read(cbuf, 0, len);       if (n > 0)           target.put(cbuf, 0, n);       return n;   }

在运行InputStreamReader的read方法

public int read(char cbuf[], int offset, int length) throws IOException {                    return sd.read(cbuf, offset, length);   }

而该InputStreamReader实际上就是System.in。而之前的close()方法已经将sd关闭了,此处再次实行read方法。则抛出IOException。然后层层捕获,终于抛出.NoSuchElementException

 

以上错误归根揭底,最基本的原因是System.in输入流已经关闭。

转载地址:http://ilkpx.baihongyu.com/

你可能感兴趣的文章
Linux安装telnet
查看>>
sap scriptfom 多语言翻译
查看>>
黄聪:3分钟学会sessionStorage用法
查看>>
Entity Framework 全面教程详解(转)
查看>>
Windows上Python2.7安装Scrapy过程
查看>>
Chapter 3:Code Style in Django
查看>>
挖掘数据金矿 领军协同创新 曙光荣膺“2016大数据创新应用领袖企业”称号
查看>>
Fast通道获得Win10 Mobile Build 14977更新
查看>>
《BackTrack 5 Cookbook中文版——渗透测试实用技巧荟萃》—第3章3.6节识别操作系统...
查看>>
linux系统防火墙iptables命令规则及配置的示例
查看>>
10 个顶尖的 Linux 开源人工智能工具
查看>>
Firefox 跟踪保护技术将页面加载时间减少 44%
查看>>
java解析虾米音乐
查看>>
rails将类常量重构到数据库对应的表中之三
查看>>
mysql 多行合并函数
查看>>
【案例】RAID卡写策略改变引发的问题
查看>>
第四十八讲:tapestry 与 淘宝kissy editor编辑器带图片上传
查看>>
Linux/Centos 重置Mysql root用户密码
查看>>
[C语言]unicode与utf-8编码转换(一)
查看>>
利用PDO导入导出数据库
查看>>