读书人

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

发布时间: 2012-03-20 14:01:11 作者: rapoo

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);


~~~~~~~
这是个native函数,是前面registerNatives()的时候注册了的.这个函数应该是把实际连接到输入输出设备的句柄传给虚拟机并赋值给in,out,err

读书人网 >J2SE开发

热点推荐