【java】 Scanner类读取控制台输入内容研究
2018-01-16 11:59
507 查看
对于用Eclipse工具进行开发的程序员来说,开始学习JAVA的时候,我们会用到java.util.Scanner类来模拟界面手动输入操作,比如下面的这段代码
一个让我很感兴趣的事情是,控制台输入,程序也能读取到,这是怎么办到的呢,现在让我们开启追踪模式,先找个简单的程序一行一行的去分析下,先看程序
那我们就看红框标注内的这行代码,进入Scanner的构造器System.in就是一个InputStream in对象,看下面的代码
红框标注内,输入流in被初始化成了InputStreamReader,再进入到InputStreamReader的构造器,看下面的代码
有几处红框标注,后面会用到,现在接着看,通过初始化InputStreamReader,把第二个红框标注内StreamDecoder进行了实例化sd,到此我们知道他们背地里干的什么事情,然后我们再返回来到
这个就是真正要初始化Scanner的老窝了,this.source 就是InputStreamReader,到这里,开头的第一句代码就完事了。
我们再来看一下
红框标注内的代码,进入到nextLine()方法内部,继续看代码
上面红框内应该就是我们的核心代码了,继续往下看,进入到findWithinHorizon方法内部
这段代码比较有意思,第一个是绿框的内容,程序用了一个while(true)死循环,保证线程一直运行,为了等我们输入,用户线程一直等待,够哥们, 另一个是红框内的内容,needInput是个是否输入标识,如果是true的化,就会执行readInput(),这个方法就是要读取我们的输入内容,核心要接近了,再给自己点耐心,继续看代码,哈哈
红框标注内的就是调用InputStreamReader的read(java.nio.CharBuffer target) ,InputStreamReader继承的Reader,read方法是父类Reader的,
图中的第二个红框就是读取数据了,调用的是Reader的read(char cbuf[], int off, int len)方法,看看那个方法是啥样的呢
StreamDecoder的read方法你是怎么玩的呢,继续看代码
虚拟机的东西慢慢也研究起来,暂时就是分享到这了。
一个让我很感兴趣的事情是,控制台输入,程序也能读取到,这是怎么办到的呢,现在让我们开启追踪模式,先找个简单的程序一行一行的去分析下,先看程序
那我们就看红框标注内的这行代码,进入Scanner的构造器System.in就是一个InputStream in对象,看下面的代码
红框标注内,输入流in被初始化成了InputStreamReader,再进入到InputStreamReader的构造器,看下面的代码
有几处红框标注,后面会用到,现在接着看,通过初始化InputStreamReader,把第二个红框标注内StreamDecoder进行了实例化sd,到此我们知道他们背地里干的什么事情,然后我们再返回来到
public Scanner(InputStream source) { this(new InputStreamReader(source), WHITESPACE_PATTERN); }这段代码告诉我们要跳转到Scanner的另一个构造器,看下面的代码
这个就是真正要初始化Scanner的老窝了,this.source 就是InputStreamReader,到这里,开头的第一句代码就完事了。
我们再来看一下
红框标注内的代码,进入到nextLine()方法内部,继续看代码
上面红框内应该就是我们的核心代码了,继续往下看,进入到findWithinHorizon方法内部
这段代码比较有意思,第一个是绿框的内容,程序用了一个while(true)死循环,保证线程一直运行,为了等我们输入,用户线程一直等待,够哥们, 另一个是红框内的内容,needInput是个是否输入标识,如果是true的化,就会执行readInput(),这个方法就是要读取我们的输入内容,核心要接近了,再给自己点耐心,继续看代码,哈哈
红框标注内的就是调用InputStreamReader的read(java.nio.CharBuffer target) ,InputStreamReader继承的Reader,read方法是父类Reader的,
图中的第二个红框就是读取数据了,调用的是Reader的read(char cbuf[], int off, int len)方法,看看那个方法是啥样的呢
abstract public int read(char cbuf[], int off, int len) throws IOException;怎么是个抽象类呢,InputStreamReader继承的Reader,所以实现了该方法,看实现代码段
public int read(char cbuf[], int offset, int length) throws IOException { return sd.read(cbuf, offset, length); }原来读取调用的是InputStreamReader里面的StreamDecoder sd, 开始的时候我们提到过后面要用的,叫你藏,我找到你了
StreamDecoder的read方法你是怎么玩的呢,继续看代码
public int read(char ac[], int i, int j) throws IOException { int k = i; int l = j; Object obj = lock; JVM INSTR monitorenter ; ensureOpen(); if(k < 0 || k > ac.length || l < 0 || k + l > ac.length || k + l < 0) throw new IndexOutOfBoundsException(); if(l == 0) return 0; int i1 = 0; if(!haveLeftoverChar) goto _L2; else goto _L1 _L1: ac[k] = leftoverChar; k++; l--; haveLeftoverChar = false; i1 = 1; if(l != 0 && implReady()) goto _L2; else goto _L3 _L3: i1; obj; JVM INSTR monitorexit ; return; _L2: if(l != 1) goto _L5; else goto _L4 _L4: int j1 = read0(); if(j1 != -1) goto _L7; else goto _L6 _L6: i1 != 0 ? i1 : -1; obj; JVM INSTR monitorexit ; return; _L7: ac[k] = (char)j1; i1 + 1; obj; JVM INSTR monitorexit ; return; _L5: i1 + implRead(ac, k, k + l); obj; JVM INSTR monitorexit ; return; Exception exception; exception; throw exception; }看看这代码,原来用到了虚拟机的东西了,终于恍然大悟了, 为啥控制台等待我们的输入
JVM INSTR monitorenter ;原来虚拟机有个监控器,在监视我们的输入内容,只要我们输入了,一回车,就读取到了CharBuffer中了
JVM INSTR monitorexit ;虚拟机的监控器就退出了,然后我们就能读取到了内容了,我们开始的String next = sc.nextLine(); 就得到了结果。
虚拟机的东西慢慢也研究起来,暂时就是分享到这了。
相关文章推荐
- Scanner类的简单用法(这里举个读取控制台输入的内容,然后输出到控制台的简单例子)
- Java Scanner类从控制台读取输入
- java中Scanner类读取文件或控制台输入
- Java 实现从控制台接受输入Scanner类
- java中Scanner类nextInt之后用nextLine无法读取输入
- JAVA读取控制台的输入【转】
- 详细整理Java 从命令控制台输入数据读取输入流System.in的几种常用方法
- java—IO流——读取键盘输入的字母并转换成大写字母输出在控制台上
- 转载 java从控制台读取输入的方法
- Java中从控制台读取输入的方法的总结
- 探讨java中Scanner类nextInt之后用nextLine无法读取输入
- Scala文件的读取与写入,从控制台输入内容
- java中Scanner类nextInt之后用nextLine无法读取输入
- java控制台程序-读取输入的字符串,其中文字符变成乱码问题
- java中从控制台读取输入的三种方法
- java读取控制台 输入
- java小例子:读取控制台用户输入数据
- I学霸官方免费教程二十二:Java常用类之接收控制台输入 Scanner类
- 编写IoDemo.java的Java应用程序,程序完成的功能是:首先读取text.txt文件内容,再通过键盘输入文件的名称为iodemo.txt,把text.txt的内容存入iodemo.txt
- java 控制台输出读取到的.xls文件内容