联机的Oracle Java规范页面将System类中的“.in”静态变量列为InputStream类型。
但是,InputStream类是抽象的。因此,不存在任何InputStream实例。
因此,开发人员必须使用子类InputStream来创建“.in”实例。
“。in”变量的确切类型是什么?
感谢。
答案 0 :(得分:2)
即使it's stored as an InputStream
,也是BufferedInputStream
:
System.out.println(System.in.getClass());
打印class java.io.BufferedInputStream
。
答案 1 :(得分:1)
您可以像这样检查
System.out.println(System.in.getClass());
将打印java.io.BufferedInputStream
答案 2 :(得分:1)
如果查看source code for Java's System class,您可以看到它最初分配给null
:
/**
* The "standard" input stream. This stream is already
* open and ready to supply input data. Typically this stream
* corresponds to keyboard input or another input source specified by
* the host environment or user.
*/
public final static InputStream in = null;
这说它是最终的...所以如何修改?好吧,System
上的这些字段很特别 - 请参阅JLS 17.5.4. Write-protected Fields。
通常,可能不会修改final和static字段。 但是,System.in,System.out和System.err是静态最终字段 由于遗留原因,必须允许通过这些方法进行更改 System.setIn,System.setOut和System.setErr。我们指的是这些 字段被写保护以区别于普通字段 最后的领域。
阅读关于该类的一些文档,您可以看到一些初始化该类的方法:
/**
* Initialize the system class. Called after thread initialization.
*/
private static void initializeSystemClass() {
....
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));
那些setIn0
,setOut0
和setErr0
都是允许更改字段的本机方法。您可以看到,在正常情况下,System.in
将是BufferedInputStream
。
private static native void setIn0(InputStream in);
private static native void setOut0(PrintStream out);
private static native void setErr0(PrintStream err);
除此之外,System
还提供了一种视图方法,允许您更改这些流的位置。例如,要更改“标准”输入流:
public static void setIn(InputStream in) {
checkIO();
setIn0(in);
}