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

先看看我写的源码

	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输入流已经关闭。

最新文章

  1. Java垃圾回收
  2. Linux study
  3. BZOJ 1110: [POI2007]砝码Odw
  4. HDU 3461 Code Lock(并查集)
  5. svn错误
  6. 身份证号码自动生成程序(Python)
  7. MATLAB对话框设计[转]
  8. oracle 里面定时执行任务,比如存储过程内容等
  9. IOS NSInvocation用法简介
  10. vim代码补全-spf13,YouCompleteMe
  11. [转]LINQ操作数据库
  12. Android 自定义对话框使用静态Handler传递参数
  13. easyui获取日期datebox中的值
  14. .net 4.5 新特性 async await 一般处理程序实例
  15. SqlServer表EXCEL数据复制的另一种方法
  16. 【RL-TCPnet网络教程】第25章 DHCP动态主机配置协议基础知识
  17. C#学习-接口
  18. java 学习------JDK1.8安装与配置
  19. 【转帖】ARM的两种不同的CPU docker 应该也是支持arm的
  20. 如何利用office绘制施工进度计划横道图?

热门文章

  1. ios 布局 素材 待整理
  2. ThinkPHP---TP功能类之联表查询
  3. php第二十九节课
  4. 模拟--P1427 小鱼的数字游戏
  5. ZOJ - 3992 - One-Dimensional Maze (思维)
  6. SIMD学习 -- 用SSE2指令作点乘和累加计算
  7. Python面向对象一些阶段性总结
  8. vue v-model 的注意点
  9. SQL学习笔记:基础SQL语句
  10. FJoi2017 1月21日模拟赛 comparison(平衡树+thita重构)