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 або якщо ви запустили виконуваний jar з GUI.
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.


7

По-перше, я боюся, що ваше запитання містить невелику помилку. У консолі класу немає методу запису методу. Натомість клас Console надає метод write (), який повертає PrintWriter. У цього друку друку є println ().

Тепер у чому різниця між

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

і

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

Якщо ви запускаєте свою програму з командного рядка, я думаю, що різниці немає. Але якщо консолі недоступно, System.console () повертає нуль, поки 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. Дивно :)
Тобі Еггітт

3

На Console.writelineЯві немає . Його в .NET.

Консолі та стандартні виходи не однакові. Якщо ви прочитаєте згадувану сторінку Javadoc , ви побачите, що програма може мати доступ до консолі, лише якщо вона викликається з командного рядка і вихід не перенаправлений так

java -jar MyApp.jar > MyApp.log

Інші подібні випадки висвітлюються у відповіді SimonJ, хоча він пропустив те, що немає Console.writeline.


Так - я вважав, що компілятор ziggy (або Javadocs) може зробити цю роботу для мене :)
SimonJ
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.