java - 为什么 Java 中的 System.out.println() 会打印到控制台?

标签 java

我在网上阅读了几篇文章,解释了 System.out.println()是在 Java 中。他们中的大多数都是这样的:

  • System is a final class in the java.lang package.
  • out is a public static object inside the System class of type PrintStream.
  • println() prints a line of text to the output stream.


我的问题是我们什么时候做 System.out.println()在我们的代码中,为什么它最终会写入控制台? This article解释了如何通过调用 System.setOut() 将其写入文件.所以我的问题转化为 System.setOut() 在哪里调用将其输出重定向到控制台?

我查了System.setOut()source .它调用setOut0()这是一个 native方法。这个方法是directly called里面initializeSystemClass()通过传递方法fdOut这是一个 FileOutputStream定义 here .我没有找到传递给 setOut0() 的控制台输出流在任何地方,我也没有找到非本地人的电话 setOut()在任何地方完成。是在 System 之外的其他地方完成的吗?在开始执行时由 JVM 类?如果是这样,有人可以指出我吗?

最佳答案

My doubt is when we do System.out.println() in our code, why it ends up in writing to console?


在任何符合 POSIX 的 shell 中,每个进程在 shell 启动时都会获得三个“标准”流:
  • “标准输入”流用于读取输入。
  • “标准输出”流用于写入普通输出。
  • “标准错误”流用于写入错误输出。

  • (同样的想法也用于许多非 POSIX 兼容的 shell。)
    对于交互式 POSIX shell,默认设置是让这些流从 shell 的“控制台”读取和写入……这可能是一个物理控制台,但更有可能是用户(最终)上的“终端模拟器”台式机。 (细节有所不同。)
    POSIX shell 允许您以各种方式重定向标准流;例如
    $ some-command < file     # read stdin from 'file'
    $ some-command > file     # write stdout to 'file'
    $ some-command 2> file    # write stderr to 'file'
    $ some-command << EOF     # read stdin from a 'here' document
      lines of input
      ...
      EOF
    $ some-command | another  # connect stdout for one command to
                              # stdin for the next one in a pipeline
    
    等等。如果您这样做,一个或多个标准流不会连接到控制台。
    进一步阅读:
  • "What are stdin, stdout and stderr on Linux?"
  • "Standard Streams"

  • 那么这与问题有什么关系呢?
    当 Java 程序启动时,System.in/out/err流连接到父进程指定的标准输入/输出/错误流;通常是一个外壳。
    System.out 的情况下,这可能是控制台(无论您如何定义),也可能是一个文件、另一个程序或... /dev/null .但是输出的去向取决于 JVM 的启动方式。
    因此,字面上的答案是“因为这是父进程告诉 Java 程序要做的事情”。

    How internally shell communicates with jvm to set standard input / output in both Windows and Linux?


    这就是 Linux、UNIX、Mac OSX 和类似设备会发生的情况。 (我不知道 Windows ......但我想它是相似的。)
    假设 shell 将运行 aaa > bbb.txt .
  • 父 shell 派生出一个子进程……共享父 shell 的地址空间。
  • 子进程关闭文件描述符1(标准输出文件描述符)
  • 子进程打开“bbb.txt”以写入文件描述符 1。
  • 子进程执行“aaa”命令,成为“aaa”命令进程。文件描述符 0、1 和 2 由 exec 调用保留。
  • “aaa”命令开始...

  • 当“aaa”命令启动时,它发现文件描述符 0 和 2(stdin 和 stderr)引用了与父 shell 相同的"file"。文件描述符 1 (stdout) 是指“bbb.txt”。
    当“aaa”是 java 时,也会发生同样的事情。命令。

    关于java - 为什么 Java 中的 System.out.println() 会打印到控制台?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61168525/

    相关文章:

    java - 替换 jdbc.support.nativejdbc 在 Spring 5 中删除

    java - LibGDX spritebatch resize relative to screen size 相对于屏幕大小

    java - XSLT 之于 XML 就像什么之于 CSV?

    java - 如何使用 espresso 根据项目文本从 ListView 中单击项目?

    java - 如何从安卓设备上传位图图像?

    java - 使用 spring mvc 和 jackson 允许带或不带根节点的 json 的正确方法

    java - 使用 Spring data Mongo 搜索嵌入数组中的文本列表

    java - logback 在 appender 中打印完整的 MDC

    java - 安卓资源文件

    java - 如何修复 Poker Deck 使其不重新实例化并将其限制为一副牌中只有 52 张牌?