console.writeline и System.out.println

120

В чем именно заключается техническая разница между console.writelineи System.out.println? Я знаю, что это System.out.printlnпишет на стандартный вывод, но разве это не то же самое, что консоль?

Я не совсем понимаю документацию для console.writeline.

Зигги
источник
6
также console.writeline не является методом Java (это .net) ... но я понимаю, о чем вы спрашиваете :)
robert_x44

Ответы:

130

Вот основные различия между использованием System.out/ .err/.in и System.console():

  • System.console()возвращает null, если ваше приложение не запущено в терминале ( хотя вы можете справиться с этим в своем приложении )
  • System.console() предоставляет методы для чтения пароля без повторения символов
  • System.outи System.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 по ряду исторических причин.

Макдауэлл
источник
Можете ли вы привести пример того, что не работает терминал?
Чао
@Richard, если вы запускаете из IDE или запускаете исполняемую банку из графического интерфейса.
aioobe
15

По сути, они одинаковы, если ваша программа запускается из интерактивного приглашения и вы не перенаправили stdin или stdout:

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; еще одно раздражение заключается в том, что часто нет Consoleдоступных объектов при порождении из другой программы, такой как Eclipse или Maven.

SimonJ
источник
7

Во-первых, боюсь, в вашем вопросе есть небольшая ошибка. В классе Console нет строки записи метода. Вместо этого класс Console предоставляет метод writer (), который возвращает PrintWriter. Этот писатель печати имеет 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

Надеюсь, мои объяснения помогут.

AlexR
источник
Чтобы код отображался как блоки кода, делайте отступ в каждой строке четырьмя пробелами. (Я только что сделал это для вас.)
BoltClock
Однако есть Console.printf и Console.format, которые пишут напрямую, без необходимости извлекать промежуточный PrintWriter. Странно :)
Тоби Эггитт
3

В Console.writelineJava нет. Это в .NET.

Консоль и стандартный выход - это не одно и то же. Если вы читаете страницу Javadoc вы упомянули , вы увидите , что приложение может иметь доступ к консоли , только если он вызывается из командной строки , а выход не перенаправлен , как это

java -jar MyApp.jar > MyApp.log

Другие подобные случаи описаны в ответе SimonJ, хотя он упустил момент, которого нет Console.writeline.

Нитеш Чандра
источник
Ага - я подумал, что компилятор Зигги (или Javadocs) может сделать эту работу за меня :)
SimonJ,