2010-06-14 6 views
7

ich jemandes Code sah und sah, dass er immer wiederAuf system.out, benötigt Klärung

erklärt
PrintStream out = System.out; 

und rief später

out.println("blah"); 

ich dies eigentlich dachte Art von ordentlich war. Ist das eine gängige Praxis? War er nur schick?

+6

Er hätte genauso leicht eine 'import static java.lang.System.out; -Deklaration am Anfang der Datei hinzufügen können. – ILMTitan

+0

@ILMTitan das ist eine noch ordentliche Lösung, aber wird natürlich nur mit Java 5 und höher arbeiten. – Alb

+2

@Alb Java 5 hat bereits die Lebensdauer des Betriebssystems erreicht. –

Antwort

7

Dies ist ein vernünftiger Ansatz. Er erstellt im Grunde einen Alias ​​für System.out. Es gibt eine Reihe von Vorteilen:

  • Weniger tippen.
  • Leichter zu später ändern Sie den Code, um auf einen anderen PrintStream auszugeben.
  • Möglicherweise eine Leistungsverbesserung, obwohl es vernachlässigbar sein wird.
+0

Punkt 1, nicht weniger als Sysout , die "System.out.println()" einfügen wird. Punkt 2, ja, aber das bedeutet auch, dass Sie den Fehler machen können, anzunehmen, dass "out" System.out.println bedeutet, weil es sonst überall im Code gemacht wurde. Es ist auch expliziter, als würde man keine kurzen Variablennamen verwenden. Punkt 3 - nein. Die Kompilierung ist schlauer als Sie. NIEMALS eine Entscheidung treffen, basierend auf dem, was Sie denken, der Compiler wird es ohne Tests zu tun - Ihre Vermutung ist fast immer falsch, der Compiler optimiert basierend darauf, dass Sie nicht knifflig - beim Schreiben der klarsten Code möglich. –

+0

@Bill K: Der Compiler ist intelligent, aber die Semantik des Feldzugriffs vs. des lokalen Variablenzugriffs ist unterschiedlich, daher kann dies im Allgemeinen nicht optimiert werden. Wer hat gesagt, println() hat den Wert von System.out nicht geändert? (Final Felder sind nicht so final wie Sie denken - schauen Sie auf System.setout().) –

+0

@Adam Crume Ich denke, ich hätte gesagt, dass der Compiler + Laufzeit ist klüger als Sie denken. Es kann sich die Tatsache ansehen, dass System.out den Code nicht ändert und in den Code einfügt, um darauf zu schreiben. In der Tat kann es den gesamten Block des Codes inline, um die tatsächliche Ausgabe zu tun, wenn es will - es wahrscheinlich nicht, aber ich wäre nicht zu überrascht, wenn es so wäre. Wenn Sie "out" aliasieren, könnte dies eine solche Laufzeitoptimierung verhindern. Alles was ich gesagt habe ist, dass, wenn Sie jemals eine Programmierentscheidung treffen, die auf theoretischen Leistungsvorteilen statt getesteten Vorteilen basiert, Sie das wirklich neu überdenken müssen. –

0

Es eine Verknüpfung ist, wenn Sie eine Menge println. tun ich es vorher an Orten getan gesehen habe, obwohl ich nicht dazu neigen, es zu tun, weil ich denke, System.out.println klarer ist, da Sie nicht brauchen, um herauszufinden, wo out wurde beauftragt. Ich habe eine Eclipse-Vorlage eingerichtet, damit ich println zu System.out.println automatisch vervollständigen kann und es ist ziemlich schnell.

+0

Eclipse hat eine integrierte Vorlage "SYSOUT", so dass Sie nicht einmal erstellen müssen Ihre eigenen :) – benjismith

+0

True, aber ich schreibe eine Menge groovy Code und auf diese Weise kann ich Println in beiden Sprachen verwenden. –

0

Nein. Nie zuvor gesehen.

Ich stimme zu. Es ist nicht zu schäbig ...

3

Um zu vermeiden, System.out.println speziell eingeben, wenn kleinen Test durchführen (ohne IDE) Ich import static java.lang.System.out anstelle

Aber das kann Sinn machen, wenn Sie den Wert System.out später ersetzen wollen, vielleicht auf einen Wrapper zu umleiten in eine Datei auf einmal

PrintStream out = new FilePrintStream("MyLogs.log"); // // System.out 

Und Schweigen der Standardausgabe. Ich wiederhole es kann Sinn machen in einigen Szenarien, weil ich dafür ein Logging-Framework verwenden würde.

BTW, wäre es besser, sie als endgültig und statisch auch zu erklären:

class YourClass { 
    private final static PrintStream out = System.out; 
} 
0

Wenn Sie Throwable.printStackTrace schauen Sie in der Dokumentation können Sie es ohne Argumente aufrufen können, und es geht nur System.out zu der Version, die einen PrintStream braucht.

Es ist durchaus üblich, Situationen zu finden, in denen eine Anzahl von verschiedenen PrintStream-Objekten herumgereicht werden kann und der Code viel einfacher zu drucken ist.

0

Es ist ein süßer Trick, aber wie die meisten süßen Tricks könnte es besser sein, es richtig zu machen.

Sobald Sie an den Punkt gelangen, an dem Sie sicher sind, dass Sie Logging durchführen wollen (sicher genug, um etwas hinzuzufügen), warum Log4J oder ein anderes Logging-System, das noch mehr Flexibilität und Power hat?

Aliasing Zeug ist irgendwie süß und Spaß, wenn Sie allein sind, sondern auch, wenn Sie eine wirklich langsam Stenotypistin und es spart Ihnen eine ganze 5 Sekunden jedes Mal, wenn Sie es eingeben (über System.out oder "sysout +<ctrl-space>" in Eclipse/Netbeans), du wirst diese Zeit beim ersten Mal zehnfach verlieren, wenn jemand - möglicherweise du - "raus" sieht. und weiß nicht sofort, was es bedeutet.

Ich meine, in einem Programm sagen wir, dass Sie getan haben, was ein anderes Plakat vorgeschlagen und "out" umgeleitet zu einer Datei anstelle von STDOUT, aber in einigen Klassen, vielleicht geht "out" immer noch zu System.out. oder vielleicht vergisst du einfach, dass du es in eine Datei umgeleitet hast. Später in dir kommen und sagen: „Nun, es sagt:

out.println("WE MADE IT"); 

aber ich sehe nicht, diese Zeile in STDOUT, was zum Teufel?“

Dann verbringen Sie 4 Stunden mit der Verfolgung einer schlechten Anzeige, anstatt den Fehler zu beheben.

+0

Wenn du Eclipse benutzt und 'out' gesehen hast, würdest du nicht einfach F3 drücken und genau sehen, wohin es geht, ohne dass Zeit verschwendet wird? Ich bin dafür, Duplikate zu entfernen und den System.out-Aufruf überall dort zu entfernen, wo er verwendet wird, um Duplikate zu entfernen. Die Gründe sind gut umrissen von der Antwort http://stackoverflow.com/questions/3041482/plain-old-system-out-question/3041495#3041495 – Alb

+0

Nicht, wenn Sie nicht zu denken, was der springende Punkt ist. Explizite Beats kurz, wenn Sie mit anderen arbeiten. Wenn du alleine bist, kann dein Code so spaßig sein, wie du willst, aber ich bin es wirklich leid, an anderen niedlichen Tricks zu arbeiten. Diese Einstellung ist etwas Liebe/Hass mit Java-Variablen Namenskonventionen. Ich meine, du würdest mit yalvn so viel Speicherplatz sparen, anstatt yetAnotherLongVariableName zu schreiben, aber einige Leute fangen an, die Wichtigkeit von expliziten Überschreibungen zu bekommen (zumindest in der Java-Welt - ich sehe immer noch eine Menge "yalvn" c-Variable Namen, als ob sie Speicher oder etwas aufnahmen) –

+0

Sicher schätze ich einen annehmbaren Methodennamen, aber in diesem Fall ist der ursprüngliche Methodenname gerade 'heraus'. Erstens glaube ich nicht, dass irgendjemand annehmen sollte, dies wäre System.out, ohne es zu überprüfen, zweitens glaube ich nicht, dass das Hinzufügen des Pakets zu jedem Aufruf der beste Weg ist, damit umzugehen. Das Extrahieren aller System.out-Aufrufe an eine Methode, z. B. "printToConsole" oder "printToLogStream", ist meiner Meinung nach besser als die Inline-Verarbeitung, da die Duplizierung entfernt wird, aber die Klarheit der Absicht erhalten bleibt. – Alb

0

Ob dies eine gute Idee ist, ist umstritten und hängt wahrscheinlich von den Umständen ab.

Auf der positiven Seite:

  • Es macht den Anwendungscode sieht einfach besser aus.
  • Es kann das Ändern des Ziels für die Ausgabe vereinfachen.

auf der Minusseite:

  • Es erhöht potentiell Kreuzkupplung; z.B. wenn die Variable out eine Instanzvariable ist oder als Parameter übergeben werden muss.
  • Es kann Probleme verursachen, wenn Ihre Anwendung System.setOut() aufrufen muss.
  • Wenn der System.out-Code gerade debuggt, wird das Erkennen und Entfernen erschwert. In der Tat, es macht wahrscheinlich PMD (etc) -Code-Qualitätsprüfungen ungültig, die solche Dinge melden.

Es sollte darauf hingewiesen werden, dass es andere Möglichkeiten gibt, dies zu tun; z.B. Ersetzen System.out.println(String) durch eine Utility-Methode printLine(String) erreicht einen ähnlichen Effekt ohne die Kreuzkopplung.

0

seit System.out ist eine final Variable, was er getan hätte wäre identisch zu Referenz System.out direkt.

es sei denn, jemand rief System.setOut(), die System.out zugewiesen wurde.

warten, was?

1

Es könnte sein, weil es im Allgemeinen nicht empfehlenswert ist, Objekte einzubeziehen und zu verwenden, die Mitglieder anderer Objekte sind. Es sieht so aus, als würde jemand nach deiner Tasche greifen, um dein Geld aus deiner Brieftasche zu holen, anstatt dich zu bitten, ihm etwas Geld zu leihen.

Dies könnte einen kleinen Vorteil haben, den Ausgabestrom bei Bedarf in eine Datei, einen Socket oder was auch immer ändern zu können.So wäre er in der Lage sein, zu ersetzen:

PrintStream out = System.out; 

mit

PrintStream out = new PrintStream(new FileOutputStream(filename)); 

Allerdings, wenn er wiederholt es über erklärt wird und immer wieder ist er wirklich der obigen Vorteil zu verlieren, weil der ganze Punkt wäre zu haben es irgendwo zentralisiert und entscheiden, wo die Protokolle an einem Ort ausgeben.

Beachten Sie, dass dies eine sehr grobe Art und Weise und die echte Standard-Praxis ist, Protokollierung verwenden. Java hat sein eigenes Paket java.util.logging out of the box, log4j ist eine andere sehr mächtige Alternative (und sehr beliebt) und es gibt andere.