当前位置: 代码迷 >> J2SE >> System.in到地是啥?解决方案
  详细解决方案

System.in到地是啥?解决方案

热度:140   发布时间:2016-04-24 02:21:13.0
System.in到地是啥?
对这个东西很感到奇怪,System是io包中的一个类,而in是它的一个静态字段,下面就不懂了,System.in是什么,是一个InputStream类?还是一个InputStream类的实例?如果是InputStream类的实例,那么System.in使用的抽象方法public abstract int read() throws IOException在System.in中重新定义了吗?如果定义了,在API文档中那里能找到?

------解决方案--------------------
没进过任何包装的一个InputStream。
建议多理解下JAVA I/O的“Decorator”模式
------解决方案--------------------
探讨
我想知道的是public abstract int read() throws IOException作为抽象类InputStream的抽象方法,怎么就能用这个不知道是啥东西的System.in的调用。

另外谢谢ZangXT的多次解答,但是Src中System的源代码好像也找不到答案呀,希望得到进一步的详细解答。

------解决方案--------------------
http://zhidao.baidu.com/question/38660871.html
建议看下,应该就会明白了,谢谢楼主的问题哦
System类里有大量的native方法,是调用本地代码的,这些代码很可能是由虚拟机来调用的. 
System类的开头有一段: 
static { 
registerNatives(); 

这段代码会在虚拟机启动的时候就执行,它在虚拟机里注册System需要使用的一些本地代码 
比如: 
private static native Properties initProperties(Properties props); 
private static native void setOut0(PrintStream out); 
在windows下的话,它就告诉虚拟机到哪个dll文件里去找相应的实现 

>然而,我知道out是一个PrintStream的对象,但我查看了有关的原代码:public final static PrintStream out = nullPrintStream(); 
>public final static InputStream in = nullInputStream(); 
在nullInputStream()方法里有注释解释为什么会设置为空: 

/** 
* The following two methods exist because in, out, and err must be 
* initialized to null. The compiler, however, cannot be permitted to 
* inline access to them, since they are later set to more sensible values 
* by initializeSystemClass(). 
*/ 
private static InputStream nullInputStream() throws NullPointerException
if (currentTimeMillis() > 0) 
return null; 
throw new NullPointerException(); 

也就说in, out, and err 初始化为null,然后会在后来由initializeSystemClass()方法类初始化成有意义的值 
/** 
* Initialize the system class. Called after thread initialization. 
*/ 
private static void initializeSystemClass() { 
props = new Properties(); 
initProperties(props); 
sun.misc.Version.init(); 
FileInputStream fdIn = new FileInputStream(FileDescriptor.in); 
FileOutputStream fdOut = new FileOutputStream(FileDescriptor.out); 
FileOutputStream fdErr = new FileOutputStream(FileDescriptor.err); 
setIn0(new BufferedInputStream(fdIn)); !!! 
setOut0(new PrintStream(new BufferedOutputStream(fdOut, 128), true)); !!! 
setErr0(new PrintStream(new BufferedOutputStream(fdErr, 128), true)); !!! 

// Enough of the world is now in place that we can risk 
// initializing the logging configuration. 
try { 
java.util.logging.LogManager.getLogManager().readConfiguration(); 
} catch (Exception ex) { 
// System.err.println("Can′t read logging configuration:"); 
// ex.printStackTrace(); 


// Load the zip library now in order to keep java.util.zip.ZipFile 
// from trying to use itself to load this library later. 
loadLibrary("zip"); 

// Subsystems that are invoked during initialization can invoke 
// sun.misc.VM.isBooted() in order to avoid doing things that should 
// wait until the application class loader has been set up. 
sun.misc.VM.booted(); 

in,out,err就是在以上方法以下三条语句里初始化的. 
setIn0(new BufferedInputStream(fdIn)); !!! 
setOut0(new PrintStream(new BufferedOutputStream(fdOut, 128), true)); !!! 
setErr0(new PrintStream(new BufferedOutputStream(fdErr, 128), true)); !!! 
看 
private static native void setIn0(InputStream in); 
  相关解决方案