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 ...
随机推荐
- 关于 . H 宏定义技巧
#ifndef LABEL #define LABEL //代码部分 #endif LABEL为一个唯一的标号,命名规则跟变量的命名规则一样.常根据它所在的头文件名来命名,例如,如果头文件的文 ...
- 详谈Struts+Hibernate+Spring三大框架
前言:对于JAVA WEB端的程序员来说,对JAVA三大框架:Struts+Hibernate+Spring的了解必不可缺,下面详细谈谈 Java三大框架主要用来做WEN应用. 三大框架:Struts ...
- java web 学习笔记 - Java Bean
1. Java Bean 是一个简单的 java 类,一般放在WEB-INF下的 classes目录下(如果没有则需要手工新建) 一个简单的Bean包括属性,getter ,setter方法,如果没有 ...
- URL解析-URLComponents
let components = URLComponents(url: fakeUrl, resolvingAgainstBaseURL: false)! http://10.100.140.84/m ...
- node遍历给定目录下特定文件,内容合并到一个文件
遍历目录用了fs.readdir这个异步方法,得到当前目录下所有的文件和目录的一个数组.然后判断: if文件,并且后缀符合设定的规则(本文例子是符合后缀ts,js)直接用同步方法写入, if目录,继续 ...
- RabbitMQ系列(八)--顺序消费模式和迅速消息发送模式
MQ使用过程中,有些业务场景需要我们保证顺序消费,而如果一个Producer,一个Queue,多个Consumer的情况下是无法保证顺序的 举例: 1.业务上产生三条消息,分别是对数据的增加.修改.删 ...
- 13EL表达式语言
EL表达式语言 EL表达式语言 JSP用于在页面上显示动态内容,通常需要在JSP页面中嵌入Java脚本以完成复杂功能.但大量的Java脚本使得JSP页面难以维护.一种类似JavaScript语言—EL ...
- 第二章 设计高质量的React组件
第二章 设计高质量的React组件 高质量React组件的原则和方法: 划分组件边界的原则: React组件的数据种类: React组件的生命周期. 2.1 易于维护组件的设计要素 1.高内聚:指的是 ...
- Gym - 101670A Amusement Anticipation(CTU Open Contest 2017 签到题)
题目&题意: 倒着找处于最后位置的等差数列的开头的位置. 例: 1 5 3 4 5 6 3 4 5 6是等差数列,它的开头的位置是3 PS: 读题真的很重要!!!!多组输入,上来就读错了!! ...
- mysql连接错误解决(ERROR 2049 (HY000): Connection using old (pre-4.1.1) authentication protocol ref used (client option 'secure_auth' enabled))
当使用mysql的新版本是,连接老版本的mysql,就会有可能报: ERROR 2049 (HY000): Connection using old (pre-4.1.1) authenticatio ...