scanner使用中遇见的问题
来源:互联网 发布:软件测试相关书籍 编辑:程序博客网 时间:2024/05/21 19:00
最近在学习的过程中遇见一个问题,问题不难但还是需要去认真对待。
先看看我写的源代码
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使用中遇见的问题
- 使用flume中遇见的问题整理
- NGUI使用过程中遇见的问题
- cocoapod 使用中遇见的问题
- thinkphp5.0使用中遇见的问题
- Scanner对象的使用问题
- excel中遇见的问题
- Spring中遇见的问题
- 开发中遇见的问题
- bootstrap中遇见的问题
- 使用loadrunner遇见的问题
- 使用 git 遇见的问题
- dll中使用ado时遇见的问题
- 在VS中使用cocos2d-x遇见的一些问题
- MFC中使用CString时遇见的问题
- Java中Scanner的使用
- Scanner 类的使用的问题
- 使用Scanner所遇到的问题
- VMware 安装虚拟机 (centos6.5)并搭建rails环境
- window2008 64位系统没有office组件问题分析及解决
- 安装Drupal过程中的问题及解决方法
- ThreadGroup和ExecutorService
- Linux下MySQL数据库常用基本操作
- scanner使用中遇见的问题
- jquery的ajax使用
- use of address of unaligned structure member 转
- 利用js的prototype属性给数组去重
- JsonConfig的常见的方法
- Android 显示原理简介
- SRP:单一职责原则
- Java heap space解决方法
- Centos Apache和tomcat集成配置,同时支持PHP和JAVA运行