System类中“.in”静态变量的确切类是什么?

时间:2014-12-20 01:16:24

标签: java class static system inputstream

联机的Oracle Java规范页面将System类中的“.in”静态变量列为InputStream类型。

但是,InputStream类是抽象的。因此,不存在任何InputStream实例。

因此,开发人员必须使用子类InputStream来创建“.in”实例。

“。in”变量的确切类型是什么?

感谢。

3 个答案:

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

那些setIn0setOut0setErr0都是允许更改字段的本机方法。您可以看到,在正常情况下,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);
}