console.writeline 和 System.out.println

137
console.writelineSystem.out.println有什么技术上的区别呢?我知道System.out.println是将内容写入标准输出, 但这与控制台不是一样的吗?
我不太理解console.writeline文档说明

1
请参见https://dev59.com/DUzSa4cB1Zd3GeqPllNf,该问题与Java控制台应用程序有关,是否仍然使用System.out。 - robert_x44
7
console.writeline不是Java方法(它属于.NET)......但我理解你的意思 :) - robert_x44
5个回答

143
以下是使用 System.out/.err/.inSystem.console() 的主要区别:
  • 如果您的应用程序没有在终端中运行,则 System.console() 返回 null (尽管您可以在应用程序中处理此问题)
  • System.console() 提供了读取密码而不回显字符的方法
  • System.outSystem.err 使用默认平台编码,而 Console 类输出方法使用控制台编码

后一种行为可能并不立即明显,但像下面这样的代码可以演示差异:

public class ConsoleDemo {
  public static void main(String[] args) {
    String[] data = { "\u250C\u2500\u2500\u2500\u2500\u2500\u2510", 
        "\u2502Hello\u2502",
        "\u2514\u2500\u2500\u2500\u2500\u2500\u2518" };
    for (String s : data) {
      System.out.println(s);
    }
    for (String s : data) {
      System.console().writer().println(s);
    }
  }
}

在我的Windows XP系统中,使用windows-1252作为系统编码,IBM850作为默认控制台编码,此代码将会输出:
???????
?Hello?
???????
┌─────┐
│Hello│
└─────┘

注意,此行为取决于控制台编码设置为与系统编码不同的编码。由于一些历史原因,在Windows上这是默认行为。

你能否提供一个在终端中无法运行的示例? - Chao
@Richard,如果你从IDE中运行程序,或者从GUI中启动可执行的JAR文件。 - aioobe
需要导入什么? - mercury

16

如果你的程序是从交互式提示符中运行的,并且你没有重定向标准输入或输出,那么它们本质上是相同的:

public class ConsoleTest {
    public static void main(String[] args) {
        System.out.println("Console is: " + System.console());
    }
}

结果是:

$ java ConsoleTest
Console is: java.io.Console@2747ee05
$ java ConsoleTest </dev/null
Console is: null
$ java ConsoleTest | cat
Console is: null

Console的存在是为了提供在交互式命令行运行时有用的功能:

  • 安全密码输入(很难跨平台实现)
  • 同步(多个线程可以提示输入,Console会将它们排队,而如果使用System.in / out,则所有提示将同时出现)。

请注意,即使只重定向了一个流,System.console()也会返回null。另一个烦恼是,通常在从其他程序(如Eclipse或Maven)生成时没有可用的Console对象。


需要导入什么? - mercury

11

首先,我很抱歉告诉您,您的问题存在一点错误。在 Console 类中不存在 writeline 方法。相反,Console 类提供了一个返回 PrintWriter 的 writer() 方法。这个打印写入器有 println() 方法。

现在,两者之间有什么区别呢?

System.console().writer().println("hello from console");

System.out.println("hello system out");

如果您从命令行运行应用程序,我认为没有区别。但是,如果控制台不可用,则 System.console() 返回 null,而 System.out 仍然存在。如果您调用应用程序并执行 STDOUT 的重定向到文件,则可能会发生这种情况。

这里是我刚刚实现的一个示例。

import java.io.Console;


public class TestConsole {
    public static void main(String[] args) {
        Console console = System.console();
        System.out.println("console=" + console);
        console.writer().println("hello from console");
    }
}

当我从命令提示符中运行应用程序时,我得到了以下结果:

$ java TestConsole
console=java.io.Console@93dcd
hello from console

但是当我将STDOUT重定向到文件时...

$ java TestConsole >/tmp/test
Exception in thread "main" java.lang.NullPointerException
        at TestConsole.main(TestConsole.java:8)

第8行是console.writer().println()

这里是/tmp/test的内容

console=null

我希望我的解释能够帮助到你。


为了使代码显示为代码块,请使用四个空格缩进每一行。(我已经为您完成了。) - BoltClock
然而,有一个Console.printf和一个Console.format,两者都可以直接写入,无需提取中间的PrintWriter。很奇怪 :) - Toby Eggitt

4

Java中没有Console.writeline,它在.NET中。

控制台和标准输出不同。如果你阅读了你提到的Javadoc页面mentioned,你会发现只有当应用程序从命令行调用并且输出未被重定向时,才能访问控制台。

java -jar MyApp.jar > MyApp.log

其他类似情况都在SimonJ的答案中涵盖了,尽管他忽略了一个重点,即没有Console.writeline

是的 - 我想Ziggy的编译器(或Javadocs)可以为我完成那个工作 :) - SimonJ

0

需要导入什么? - mercury

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