console.writeline und System.out.println

120

Was genau ist der technische Unterschied zwischen console.writelineund System.out.println? Ich weiß, dass System.out.printlnin die Standardausgabe geschrieben wird, aber ist dies nicht dasselbe wie die Konsole?

Ich verstehe die Dokumentation für nicht vollständig console.writeline.

zickig
quelle
6
Auch console.writeline ist keine Java-Methode (es ist .net) ... aber ich verstehe, was Sie fragen :)
robert_x44

Antworten:

130

Hier sind die Hauptunterschiede zwischen der Verwendung von System.out/ .err/.in und System.console():

  • System.console()Gibt null zurück, wenn Ihre Anwendung nicht in einem Terminal ausgeführt wird ( obwohl Sie dies in Ihrer Anwendung behandeln können ).
  • System.console() Bietet Methoden zum Lesen von Kennwörtern ohne Echo von Zeichen
  • System.outund System.errverwenden Sie die Standardplattformcodierung, während die ConsoleKlassenausgabemethoden die Konsolencodierung verwenden

Dieses letztere Verhalten ist möglicherweise nicht sofort offensichtlich, aber Code wie dieser kann den Unterschied demonstrieren:

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

Unter Windows XP mit einer Systemcodierung von Windows-1252 und einer Standardkonsolencodierung von IBM850 schreibt dieser Code:

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

Beachten Sie, dass dieses Verhalten davon abhängt, dass die Konsolencodierung auf eine andere Codierung als die Systemcodierung eingestellt ist. Dies ist aus einer Reihe historischer Gründe das Standardverhalten unter Windows.

McDowell
quelle
Können Sie ein Beispiel dafür finden, wie Sie nicht in einem Terminal ausgeführt werden?
Chao
@Richard, wenn Sie auf "Ausführen von einer IDE" klicken oder wenn Sie eine ausführbare JAR-Datei über eine GUI starten.
Aioobe
15

Sie sind im Wesentlichen gleich, wenn Ihr Programm über eine interaktive Eingabeaufforderung ausgeführt wird und Sie stdin oder stdout nicht umgeleitet haben:

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

Ergebnisse in:

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

Der Grund dafür Consolebesteht darin, Funktionen bereitzustellen, die in dem speziellen Fall nützlich sind, in dem Sie über eine interaktive Befehlszeile ausgeführt werden:

  • sichere Passworteingabe (schwer plattformübergreifend)
  • Synchronisation (mehrere Threads können zur Eingabe Consoleauffordern und stellen sie gut in die Warteschlange, während bei Verwendung von System.in/out alle Eingabeaufforderungen gleichzeitig angezeigt werden).

Beachten Sie oben, dass das Umleiten eines der Streams zur System.console()Rückkehr führt null. Eine weitere Irritation ist, dass oft kein ConsoleObjekt verfügbar ist, wenn es aus einem anderen Programm wie Eclipse oder Maven erzeugt wird.

SimonJ
quelle
7

Zuerst fürchte ich, Ihre Frage enthält einen kleinen Fehler. In der Klasse Console gibt es keine Methoden-Writeline. Stattdessen stellt die Klasse Console die Methode writer () bereit, die PrintWriter zurückgibt. Dieser Printwriter hat println ().

Was ist nun der Unterschied zwischen

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

und

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

Wenn Sie Ihre Anwendung über die Befehlszeile ausführen, gibt es meines Erachtens keinen Unterschied. Wenn die Konsole jedoch nicht verfügbar ist, gibt System.console () null zurück, solange System.out noch vorhanden ist. Dies kann passieren, wenn Sie Ihre Anwendung aufrufen und STDOUT in eine Datei umleiten.

Hier ist ein Beispiel, das ich gerade implementiert habe.

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

Als ich die Anwendung über die Eingabeaufforderung ausführte, wurde Folgendes angezeigt:

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

aber als ich das STDOUT in die Datei umgeleitet habe ...

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

Zeile 8 ist console.writer().println().

Hier ist der Inhalt von / tmp / test

console=null

Ich hoffe meine Erklärungen helfen.

AlexR
quelle
Damit Code als Codeblöcke angezeigt wird, rücken Sie jede Zeile mit vier Leerzeichen ein. (Ich habe das aber gerade für dich getan.)
BoltClock
Es gibt jedoch eine Console.printf und eine Console.format, die beide direkt schreiben, ohne dass der dazwischenliegende PrintWriter extrahiert werden muss.
Seltsam
3

Console.writelineIn Java gibt es keine . Es ist in .NET.

Konsole und Standardausgang sind nicht gleich. Wenn Sie die von Ihnen erwähnte Javadoc-Seite lesen , werden Sie feststellen, dass eine Anwendung nur dann auf eine Konsole zugreifen kann, wenn sie über die Befehlszeile aufgerufen wird und die Ausgabe nicht wie folgt umgeleitet wird

java -jar MyApp.jar > MyApp.log

Andere solche Fälle werden in SimonJs Antwort behandelt, obwohl er den Punkt verpasst hat, dass es keinen gibt Console.writeline.

Nithesh Chandra
quelle
Yup - Ich dachte, Ziggys Compiler (oder die Javadocs) könnten diesen Job für mich
erledigen