Java中的System.out是什么类型?

5

我只是Java中的新手。我想知道如何使用System.out.println()outSystem类中的静态字段。 out的类型是PrintStream。但是当我看到PrintStream类的构造函数时,它接受一个OutputStream类型的参数,据我所知我们无法创建抽象类的对象。在这种情况下,我们必须将某个子类的对象传递给PrintStream的构造函数。那么这个类是什么?同样的问题也出现在System.in上。它也是一个InputStream的引用,但由于InputStream是抽象的,因此它指向的对象的类型是什么?


您可以使用Java的反射机制在运行时检查所有重要对象信息。 - Dariusz
2
尝试使用 System.out.println(System.out.getClass()); 或在调试器中查看它。 ;) - Peter Lawrey
1
@PeterLawrey 这将打印class java.io.PrintStream,仅此而已 :) 使用调试器的想法更有效 ;) - Andremoniy
4个回答

3

PrintStream包装了BufferedOutputStream,后者又包装了FileOutputStream,它将输出写入控制台,而控制台拥有自己的FileDescriptor


我想补充一点,静态字段System.out不需要用户进行实例化,只需直接使用即可。我感觉问题的关键在于楼主对此理解上有些困难。 - Fildor
@Fildor我没有那种感觉。在我看来,这只是一个理论问题。 - Andremoniy
1
从技术上讲,它是一个“FileDescriptor”。并没有使用“File”类。 - Peter Lawrey
1
@PeterLawrey 谢谢你,这是我的笔误。我会修正它的。 - Andremoniy

3

查看类结构的简单方法是在调试器中检查它。

正如你所看到的,@Andremonify的描述基本上就是你需要的。

FileDescriptor

  • 0是System.in
  • 1是System.out
  • 2是System.err
  • 3+用于其他文件

enter image description here


FileInputStream for stdin, FileOutputStream for stdout. What about stderr - overexchange
@overexchange stderr和stdout基本相同。 - Peter Lawrey
可以。您也能评论一下这个查询的第一部分吗?涉及到流的想法。 - overexchange

1

是的,outPrintStream 类型。而且 PrintStream 的构造函数需要 OutputStream 类型。 OutputStream 是抽象类。但是任何超类引用都可以引用子类对象而不需要转换,所以 PrintStream 的构造函数具有 OutputStream 引用,但是这个引用必须引用 OutputStream 的子类之一,比如 FileOutputStream


1

关于 System.out 的实现还有一些需要说的事情。

  1. The actual implementation class of System.out is not specified. The javadocs don't say what it is. We observe (in various way) that Oracle Java and OpenJDK Java implement the "stack" in a particular way (see other answers), but this could change in the future.

  2. The System::setOut(PrintStream) method can be used to modify what System.out is bound to. If that happens, any assumptions about implementation classes may be incorrect.

  3. It turns out that you can do this:

      System.setOut(null);
    

    so System.out could be null. However, with current implementations, System.out won't be null unless you set it to null.

所有规范实际上保证的是,System.out 的值将具有与 PrintStream 兼容的赋值类型。

但是我们知道实现类要么是PrintStream,要么是PrintStream的子类,对吧? - Bernhard Barker
是的,这或多或少就是“赋值兼容”的意思!(但是...有点争议...null没有实现类。这就是为什么“赋值兼容”在技术上比你说的更准确的原因。) - Stephen C

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接