2010-06-14 5 views
7

Je regardais le code de quelqu'un et a vu qu'il a déclaré à plusieurs reprisesSur system.out, la clarification nécessaire

PrintStream out = System.out; 

et plus tard appelé

out.println("blah"); 

Je pensais que c'était un peu propre. Est-ce une pratique courante? Était-il juste en train d'être chic?

+6

Il aurait tout aussi bien pu ajouter une déclaration 'import static java.lang.System.out;' en haut du fichier. – ILMTitan

+0

@ILMTitan est une solution encore plus ordonnée, mais bien sûr ne fonctionnera qu'avec java 5 et plus. – Alb

+2

@Alb Java 5 a déjà terminé sa période de fin de vie. –

Répondre

7

Ceci est une approche raisonnable. Il crée essentiellement un alias pour System.out. Il y a un certain nombre d'avantages:

  • Moins de frappe.
  • Plus facile à modifier plus tard le code pour la sortie vers un autre PrintStream.
  • Peut-être une amélioration des performances, même si elle sera négligeable.
+0

point 1, pas moins de sysout qui va insérer "System.out.println()". Point 2, oui mais cela signifie aussi que vous pouvez faire l'erreur de supposer que "out" signifie System.out.println parce que c'est ainsi que cela a été fait partout ailleurs dans le code. C'est aussi plus explicite, comme ne pas utiliser de noms de variables courts. Point 3 - non La compilation est plus intelligente que vous. Ne prenez JAMAIS de décision en fonction de ce que le compilateur va faire sans le baser sur le test - votre estimation est presque toujours fausse, le compilateur optimise en fonction du fait que vous n'êtes pas compliqué - en écrivant le code le plus clair possible. –

+0

@Bill K: Le compilateur est intelligent, mais la sémantique de l'accès au champ par rapport à l'accès à la variable locale est différente, donc il ne peut pas optimiser cela en général. Qui a dit que println() n'a pas changé la valeur de System.out? (Les champs finaux ne sont pas aussi fin que vous le pensez - regardez System.setout().) –

+0

@Adam Crume Je suppose que j'aurais dû dire que le compilateur + runtime est plus intelligent que vous ne le pensez. Il peut regarder le fait que System.out ne change pas et aligner le code pour y écrire. En fait, il peut aligner tout le bloc de code pour faire la sortie réelle s'il le souhaite - ce n'est probablement pas le cas, mais je ne serais pas trop surpris si c'était le cas. Si vous deviez alias "out", cela pourrait empêcher une telle optimisation de l'exécution. Fondamentalement, tout ce que je disais, c'est que si vous prenez jamais une décision de programmation basée sur des avantages de performance théoriques au lieu d'avantages testés, vous devez vraiment repenser cela. –

0

Il est un raccourci si vous faites beaucoup de println. je l'ai vu faire dans des endroits auparavant, bien que je tendance à ne pas le faire parce que je pense System.out.println est plus claire puisque vous n'avez pas besoin de savoir où out était assigné. Je configure un modèle d'éclipse afin que je puisse compléter automatiquement println à System.out.println et c'est assez rapide.

+0

Eclipse a un modèle intégré "sysout", donc vous n'avez même pas besoin de créer votre propre :) – benjismith

+0

C'est vrai, mais j'écris beaucoup de code groovy et de cette façon je peux utiliser println dans les deux langues. –

0

Non. Je n'ai jamais vu ça avant.

Je suis d'accord. Ce n'est pas trop moche ...

3

Pour éviter de taper System.out.println spécialement lors de l'exécution petit test (sans IDE) J'utilise import static java.lang.System.out à la place

Mais cela peut donner un sens si vous voulez remplacer la valeur de System.out plus tard, peut-être à un emballage pour rediriger vers un fichier

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

Et de désactiver la sortie standard à la fois. Je le répète peut avoir un sens sur certains scénarios, car pour cela, je voudrais utiliser un cadre de journalisation.

BTW, il serait préférable de le déclarer comme définitif et statique aussi:

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

Si vous regardez Throwable.printStackTrace dans la documentation que vous pouvez appeler sans arguments, et il passe juste System.out à la version qui prend un PrintStream.

Il est assez fréquent de trouver des situations où un certain nombre d'objets PrintStream différents pourraient être transmis et cela rend le code d'impression beaucoup plus simple.

0

C'est un truc mignon, mais comme la plupart des astuces mignonnes, il vaudrait peut-être mieux faire les choses correctement. Une fois arrivé au point où vous êtes sûr de vouloir vous connecter (bien sûr d'ajouter quelque chose comme ça), pourquoi ne pas simplement avoir Log4J ou un autre système de journalisation qui a encore plus de flexibilité et de puissance?Aliasing est un peu mignon et amusant si vous êtes seul, mais même si vous êtes un dactylo très lent et il vous fait gagner 5 secondes chaque fois que vous le tapez (sur System.out ou "sysout +<ctrl-space>" dans eclipse/netbeans), vous perdrez ce temps dix fois la première fois que quelqu'un - peut-être vous - verra «sortir». et ne sait pas immédiatement ce que cela signifie. Je veux dire, dans un programme disons que vous avez fait ce que d'autres affiches ont suggéré et redirigé "out" pour aller dans un fichier à la place de STDOUT mais dans certaines classes, "out" peut aller jusqu'à System.out. ou peut-être oubliez-vous simplement que vous l'avez redirigé vers un fichier. Plus tard, vous venez et dites « bien, il est dit:

out.println("WE MADE IT"); 

mais je ne vois pas cette ligne dans STDOUT, ce que l'enfer? »

Ensuite, vous passez 4 heures à suivre une mauvaise indication au lieu de corriger le bogue.

+0

Si vous utilisiez Eclipse et que vous voyiez 'out', n'appuyez-vous pas sur F3 et voyez exactement où cela se passe sans perdre de temps? Je suis tout pour supprimer la duplication et supprimer l'appel System.out chaque fois qu'il est utilisé supprime la duplication. Les raisons sont bien décrites par la réponse http://stackoverflow.com/questions/3041482/plain-old-system-out-question/3041495#3041495 – Alb

+0

Pas si vous n'y pensiez pas, quel est le point entier. Bat vocal explicite lorsque vous travaillez avec d'autres. Lorsque vous êtes seul, votre code peut être aussi amusant que vous le souhaitez, mais je suis vraiment fatigué de travailler sur des trucs mignons d'autres personnes. Cette attitude devient de l'amour/de la haine avec les conventions de nommage des variables Java. Je veux dire, vous économiserez autant d'espace en utilisant yalvn au lieu de taper encoreAnotherLongVariableName, mais certaines personnes commencent à avoir l'importance de l'explicite plus brève (au moins dans le monde Java - je vois encore beaucoup de variables "yalvn" c noms, comme s'ils prenaient de la mémoire ou quelque chose) –

+0

Bien sûr, j'apprécie un nom de méthode décent, mais dans ce cas, le nom de la méthode originale est juste 'out'. Premièrement, je ne pense pas que quiconque devrait supposer que ce serait System.out sans le vérifier, ensuite je ne pense pas que l'ajout du paquet à chaque invocation soit la meilleure façon de le gérer. Extraire tous les appels System.out à une méthode, par exemple, «printToConsole» ou «printToLogStream» est mieux que de les laisser en ligne à mon avis car il supprime la duplication, mais conserve la clarté de l'intention. – Alb

0

Que ce soit une bonne idée est discutable, et dépend probablement des circonstances.

Du côté plus:

  • Il fait le code d'application regard plus propre.
  • Cela peut simplifier le changement de destination pour la sortie.

Du côté moins:

  • Il augmente potentiellement couplage croisé; par exemple. si la variable out est une variable d'instance ou doit être transmise en tant que paramètre.
  • Cela peut causer des problèmes si votre application doit appeler System.setOut().
  • Si le code System.out ne fait que déboguer, il est plus difficile à remarquer et à supprimer. En effet, cela annule probablement les contrôles de qualité du code PMD (etc) qui rapportent ce genre de choses.

Il convient de noter qu'il existe potentiellement d'autres façons de le faire; par exemple. le remplacement System.out.println(String) par une méthode utilitaire printLine(String) permet d'obtenir un effet similaire sans le couplage croisé.

0

puisque System.out est une variable final, ce qu'il a fait serait identitcal à référencer System.out directement.

sauf si quelqu'un a appelé System.setOut() qui a réaffecté System.out.

attente, quoi?

1

Il se peut qu'en général, il ne soit pas recommandé d'explorer et d'utiliser des objets appartenant à d'autres objets. Il est vu comme quelqu'un qui cherche votre poche pour sortir votre argent de votre porte-monnaie au lieu de vous demander de lui prêter de l'argent.

Il pourrait y avoir un léger avantage à ce qui serait de pouvoir changer le flux de sortie si nécessaire pour un fichier, une socket ou autre.Alors, il serait en mesure de remplacer:

PrintStream out = System.out; 

avec

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

Cependant, s'il est à plusieurs reprises déclare encore et encore, il perd vraiment l'avantage ci-dessus, parce que le point de l'ensemble serait d'avoir quelque part centralisé et décider où sortir les journaux en un seul endroit. Notez que c'est une manière très grossière et que la pratique standard est d'utiliser la journalisation. Java a son propre paquet java.util.logging sorti de la boîte, log4j est une autre alternative très puissante (et très populaire) et il y en a d'autres.

Questions connexes