console.writeline i System.out.println


120

Jaka jest dokładnie różnica techniczna między console.writelinei System.out.println? Wiem, że System.out.printlnpisze na standardowe wyjście, ale czy to nie to samo, co konsola?

Nie do końca rozumiem dokumentację programu console.writeline.



6
również console.writeline nie jest metodą java (to jest .net) ... ale rozumiem, o co pytasz :)
robert_x44

Odpowiedzi:


130

Oto podstawowe różnice między używaniem System.out/ .err/.in a System.console():

  • System.console()zwraca wartość null, jeśli twoja aplikacja nie jest uruchomiona na terminalu ( chociaż możesz sobie z tym poradzić w swojej aplikacji )
  • System.console() zapewnia metody odczytu hasła bez powtarzających się znaków
  • System.outi System.errużywają domyślnego kodowania platformy, podczas gdy Consolemetody wyjściowe klas używają kodowania konsoli

To drugie zachowanie może nie być od razu oczywiste, ale taki kod może pokazać różnicę:

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);
    }
  }
}

Na moim Windows XP, który ma kodowanie systemowe Windows-1252 i domyślne kodowanie konsoli IBM850, ten kod zapisze:

???????
?Hello?
???????
┌─────┐
Hello
└─────┘

Należy zauważyć, że to zachowanie zależy od ustawienia kodowania konsoli na inne kodowanie niż kodowanie systemowe. Jest to domyślne zachowanie w systemie Windows z kilku powodów historycznych.


Czy możesz uzyskać przykład, że nie działa w terminalu?
Chao,

@Richard, jeśli trafisz uruchom z IDE lub jeśli uruchomisz plik wykonywalny jar z GUI.
aioobe

15

Zasadniczo są takie same, jeśli program jest uruchamiany z interaktywnego znaku zachęty i nie przekierowano na stdin ani stdout:

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

prowadzi do:

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

Powodem Consolejest zapewnienie funkcji przydatnych w konkretnym przypadku uruchamiania z interaktywnego wiersza poleceń:

  • bezpieczne wprowadzanie hasła (trudne do wykonania na wielu platformach)
  • synchronizacja (wiele wątków może pytać o dane wejściowe i Consoleładnie je ustawiać w kolejce, podczas gdy jeśli używałeś System.in/out, wszystkie podpowiedzi pojawią się jednocześnie).

Zauważ powyżej, że przekierowanie nawet jednego ze strumieni powoduje System.console()powrót null; kolejną irytacją jest to, że często nie ma Consoledostępnego obiektu, gdy jest on tworzony z innego programu, takiego jak Eclipse lub Maven.


7

Po pierwsze, obawiam się, że twoje pytanie zawiera mały błąd. W klasie Console nie istnieje zapis metody. Zamiast tego klasa Console udostępnia metodę writer (), która zwraca wartość PrintWriter. Ten program do zapisywania wydruków ma println ().

Jaka jest różnica między

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

i

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

Jeśli uruchamiasz aplikację z wiersza poleceń, myślę, że nie ma różnicy. Ale jeśli konsola jest niedostępna, System.console () zwraca wartość null, podczas gdy System.out nadal istnieje. Może się tak zdarzyć, jeśli wywołasz aplikację i przekierujesz STDOUT do pliku.

Oto przykład, który właśnie zaimplementowałem.

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");
    }
}

Kiedy uruchomiłem aplikację z wiersza poleceń, otrzymałem następujące informacje:

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

ale kiedy przekierowałem STDOUT do pliku ...

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

Linia 8 to console.writer().println().

Oto zawartość / tmp / test

console=null

Mam nadzieję, że moje wyjaśnienia pomogą.


Aby kod był wyświetlany jako bloki kodu, wcięcie każdego wiersza czterema spacjami. (Jednak właśnie to dla ciebie zrobiłem.)
BoltClock

Istnieje jednak Console.printf i Console.format, z których oba zapisują bezpośrednio, bez konieczności wyodrębniania pośredniczącego PrintWriter. Dziwne :)
Toby Eggitt

3

Nie ma Console.writelinew Javie. Jest w .NET.

Konsola i standardowe wyjście to nie to samo. Jeśli czytasz stronę Javadoc ty wspomniało , widać, że aplikacja może mieć dostęp do konsoli tylko wtedy, gdy jest wywoływany z linii poleceń i wyjście nie jest przekierowywany tak

java -jar MyApp.jar > MyApp.log

Inne takie przypadki są objęte odpowiedzią SimonaJa, chociaż nie zauważył, że nie ma Console.writeline.


Tak - pomyślałem, że kompilator ziggy'ego (lub Javadocs) może zrobić to za mnie :)
SimonJ
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.