scanner使用中遇见的问题
近期在学习的过程中遇见一个问题,问题不难但还是须要去认真对待。
先看看我写的源码
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输入流已经关闭。
scanner使用中遇见的问题的更多相关文章
- [Intellij] Intellij IDEA 使用中遇见的问题
问题集锦 [IntelliJ IDEA14 + tomcat 设置热部署] 点击deployment查看Deploy at the server startup 中tomcat每次所运行的包是 xxx ...
- Git 使用中遇见的各种问题及解决办法
一.修改提交代码的用户名以及提交邮箱,(推荐使用方法2,一劳永逸) 方法1(修改.git/config文件): step1:进入工程.git文件夹 step2:vim config step3:末行添 ...
- 记录一次mybatis genertor使用以及mapper扫描遇见的问题
本记录适用初次接触mybatis,大神忽略... 整体上分两个部分: 1.使用mybatis genertor自动生成代码 2.mapper的扫描 1.使用mybatis genertor自动生成代码 ...
- (1)QlikView概要
本文的内容,以学习的两个合伙人: I.什么是Qlikview II. QlikView 的优点和缺点 1.1什么是QlikView 1.1什么是QlikView QlikView是一个工具,一个商业智 ...
- word文档转pdf,支持.doc和.docx,另附抽取pdf指定页数的方法
公司有个需求,需要将word转成pdf并且抽取首页用以展示,word文档有需要兼容.doc和.docx两种文档格式.其中.docx通过poi直接就可以将word转成pdf,.doc则无法这样实现,上网 ...
- Appium python自动化测试系列之认识Appium(四)
4.1界面认识 在之前安装appium的时候说过我们有两种方法安装,也就有两种结果,一种是有界面的,一种是没有界面的,首先我们先讲一下有界面的,以及界面有哪些东西. 首先看第一幅图,如果你的是win ...
- Appium+python自动化(八)- 初识琵琶女Appium(千呼万唤始出来,犹抱琵琶半遮面)- 下(超详解)
简介 通过上一篇宏哥给各位小伙伴们的引荐,大家移动对这位美女有了深刻的认识,而且她那高超的技艺和婀娜的身姿久久地浮现在你的脑海里,是不是这样呢???不要害羞直接告诉宏哥:是,就对了.宏哥要的就是这个 ...
- Caffe搭建:常见问题解决办法和ubuntu使用中遇到问题(持续更新)
严正声明: 在linux下面使用命令行操作时,一定要懂得命令行的意思,然后再执行,要不然在不知道接下来会发生什么的情况下输入一通命令,linux很有可能崩掉. 因为在linux下面,使用sudo以及r ...
- 【Java】 Scanner类的几个方法
通过 Scanner 类可以获取用户的输入,创建 Scanner 对象的基本语法如下: Scanner sc = new Scanner(System.in); nextInt().next()和ne ...
随机推荐
- mongo 3.4分片集群系列之五:详解平衡器
这个系列大致想跟大家分享以下篇章: 1.mongo 3.4分片集群系列之一:浅谈分片集群 2.mongo 3.4分片集群系列之二:搭建分片集群--哈希分片 3.mongo 3.4分片集群系列之三:搭建 ...
- 本地调试hbase
需求说明 如果要本地调试Hbase程序,那么可以用本地连接集群的方式 配置文件 在maven里,配置文件cluster.properties放在target/classes里 cluster.prop ...
- HDU_1864_最大报销额_01背包
最大报销额 Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u Submit Status ...
- java内存组成
java内存组成介绍:堆(Heap)和非堆(Non-heap)内存 按照官方的说法:“Java 虚拟机具有一个堆,堆是运行时数据区域,所有类实例和数组的内存均从此处分配.堆是在 Java 虚拟机启动 ...
- blender--(凹凸贴图)................https://jingyan.baidu.com/article/9f63fb917c4becc8400f0ea8.html
在blender中直接绘制模型凹凸纹理细节 听语音 | 浏览:32 | 更新:2018-02-20 11:18 1 2 3 4 5 6 7 分步阅读 在blender中为了表现更多的模型细节,我们会常 ...
- CAD得到范围内实体(网页版)
主要用到函数说明: IMxDrawSelectionSet::Select 构造选择集.详细说明如下: 参数 说明 [in] MCAD_McSelect Mode 构造选择集方式 [in] VARIA ...
- vivo手机执行input命令提示killed
异常现象: 使用vivo手机时发现通过inputManager发送按键.执行屏幕滑动等动作失效,相关API并没有任何异常抛出,继续跟踪发现shell控制台执行input进行屏幕滑动.发送文本.模拟按键 ...
- IOS上MediaPlayer framework实现视频播放
播放电影文件: iOS sdk中可以使用MPMoviePlayerController来播放电影文件.但是在iOS设备上播放电影文件有严格的格式要求,只能播放下面两个格式的电影文件. • H.264 ...
- Qt中实现无边框的窗体
1 自定义窗体类继承自QWidget 2 在构造函数中设置无边框效果 setWindowFlags(Qt::FramelessWindowHint);//无边框 setAttribute(Qt::WA ...
- HDU4496 D-City【基础并查集】
Problem Description Luxer is a really bad guy. He destroys everything he met. One day Luxer went to ...