我知道,在java中,抽象类只能被引用而不能被初始化。 InputStream
是一个抽象类,在 System
类中我注意到下面的声明,
static InputStream in;
因此,如果我们想让代码 System.in.read()
工作,变量 in
需要被初始化。
我的问题是 java 是如何做到的?如果 InputStream
是抽象的,其他一些子类应该扩展它。默认情况下是哪个类?
最佳答案
幸运的是,很容易检查 System.in
对象的类型指的是:
System.out.println(System.in.getClass().getName());
打印(对我来说):
java.io.BufferedInputStream
所以它是一个 BufferedInputStream
。它包裹着什么?嗯,
Field field = FilterInputStream.class.getDeclaredField("in");
field.setAccessible(true);
System.out.println(field.get(System.in).getClass().getName());
打印(再次对我而言):
java.io.FileInputStream
因此,System.in
是一个包裹在 BufferedInputStream
中的 FileInputStream
。这是有道理的,如果您认为大多数操作系统都将控制台视为文件。事实上,这个 FileInputStream
从 FileDescriptor.in
引用的"file"中读取。 .
通过搜索对 FileDescriptor.in
的引用,我找到了初始化 System.in 的代码:在私有(private)静态方法 System.initializeSystemClass
中:
FileInputStream fdIn = new FileInputStream(FileDescriptor.in);
FileOutputStream fdOut = new FileOutputStream(FileDescriptor.out);
FileOutputStream fdErr = new FileOutputStream(FileDescriptor.err);
setIn0(new BufferedInputStream(fdIn));
setOut0(newPrintStream(fdOut, props.getProperty("sun.stdout.encoding")));
setErr0(newPrintStream(fdErr, props.getProperty("sun.stderr.encoding")));
initializeSystemClass
可能由 native 代码调用,因为似乎没有对它的引用。
关于java - InputStream类型的System.in是如何初始化的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28390404/