对这个东西很感到奇怪,System是io包中的一个类,而in是它的一个静态字段,下面就不懂了,System.in是什么,是一个InputStream类?还是一个InputStream类的实例?如果是InputStream类的实例,那么System.in使用的抽象方法public abstract int read() throws IOException在System.in中重新定义了吗?如果定义了,在API文档中那里能找到?
------解决方案--------------------
没进过任何包装的一个InputStream。
建议多理解下JAVA I/O的“Decorator”模式
------解决方案--------------------
------解决方案--------------------
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);