2010-06-14 9 views
7

yo estaba buscando en el código de otra y vio que él declaró en repetidas ocasionesEn system.out, clarifique

PrintStream out = System.out; 

y más tarde llamó

out.println("blah"); 

realidad pensé que esto era una especie de limpia. ¿Es esta una práctica común? ¿Estaba solo siendo elegante?

+6

Podría haber agregado fácilmente una declaración 'import static java.lang.System.out;' en la parte superior del archivo. – ILMTitan

+0

@ILMTitan, que es una solución aún más ordenada, pero por supuesto solo funcionará con Java 5 en adelante. – Alb

+2

@Alb Java 5 ya ha completado su período de fin de vida útil. –

Respuesta

7

Este es un enfoque razonable. Básicamente está creando un alias para System.out. Hay una serie de ventajas:

  • Menos tipeo.
  • Más fácil de cambiar el código para enviarlo a un PrintStream diferente.
  • Posiblemente una mejora en el rendimiento, aunque será insignificante.
+0

punto 1, no menos de sysout que insertará "System.out.println()". Punto 2, sí, pero eso también significa que puede cometer el error de asumir que "salir" significa System.out.println porque así es como se hizo en todas partes del código. También es más explícito, como no usar nombres cortos de variables. Punto 3 - no. La compilación es más inteligente que tú. NUNCA tome una decisión basada en lo que cree que el compilador va a hacer sin basarlo en las pruebas (su suposición es casi siempre incorrecta, el compilador optimiza en función de que no sea complicado) al escribir el código más claro posible. –

+0

@Bill K: el compilador es inteligente, pero la semántica del acceso de campo frente al acceso variable local es diferente, por lo que no puede optimizar esto en general. ¿Quién puede decir que println() no cambió el valor de System.out? (Los campos finales no son tan definitivos como cabría pensar - mire System.setout().) –

+0

@ Adam Crume Supongo que debería haber dicho que el compilador + tiempo de ejecución es más inteligente de lo que cree. Puede ver el hecho de que System.out no está cambiando y en línea el código para escribir en él. De hecho, puede alinear todo el bloque de código para hacer la salida real si lo desea, probablemente no, pero no estaría demasiado sorprendido si lo hiciera. Si tuviera que alias "out", podría evitar dicha optimización de tiempo de ejecución. Básicamente, todo lo que estaba diciendo es que SI alguna vez tomas una decisión de programación basada en las ventajas de rendimiento teórico en lugar de las ventajas probadas, realmente necesitas reconsiderar eso. –

0

Es un acceso directo, si está haciendo una gran cantidad de println. que he visto hacer en los lugares antes, aunque no tienden a hacerlo porque creo System.out.println es clara ya que no es necesario averiguar dónde out fue asignado. Configuré una plantilla de eclipse para poder autocompletar println a System.out.println y es bastante rápido.

+0

Eclipse tiene una plantilla incorporada "sysout", por lo que ni siquiera tenía que crear su propia :) – benjismith

+0

Cierto, pero escribo un montón de código groovy y de esta manera puedo usar println en cualquier idioma. –

0

No. Nunca he visto eso antes.

Estoy de acuerdo. No está nada mal ...

3

Para evitar tener que escribir System.out.println especialmente cuando se realiza pequeña prueba (sin un IDE) utilizo import static java.lang.System.out lugar

pero que puede tener sentido si desea sustituir el valor de System.out más tarde, tal vez a una envoltura para redirigir a un archivo

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

Y silencie la salida estándar a la vez. Lo repito puede tiene sentido en algunos escenarios, porque para esto utilizaría un marco de registro.

Por cierto, sería mejor declarar como final y estática también:

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

Si nos fijamos en Throwable.printStackTrace en la documentación se le puede llamar sin argumentos, y que sólo pasa System.out a la versión que toma un PrintStream.

Es bastante común encontrar situaciones en las que se pueden pasar varios objetos diferentes de PrintStream y hace que el código de impresión sea mucho más simple.

0

Es un lindo truco, pero como la mayoría de los trucos es mejor hacerlo bien.

Una vez que llega al punto en el que está seguro de que desea iniciar sesión (lo suficiente como para agregar algo así), ¿por qué no simplemente obtener Log4J o algún otro sistema de registro que tenga aún más flexibilidad y potencia?

Aliasing es algo lindo y divertido si estás solo, pero incluso si eres un mecanógrafo muy lento y te ahorra 5 segundos enteros cada vez que lo escribes (a través de System.out o "sysout +<ctrl-space>" en eclipse/netbeans), perderá ese tiempo diez veces la primera vez que alguien, posiblemente usted, vea "fuera". y no sabe de inmediato lo que significa.

Quiero decir, en un programa digamos que usted hizo lo que otro cartel sugirió y redirigió "fuera" para ir a un archivo en lugar de STDOUT pero en algunas clases, tal vez "fuera" todavía va a System.out. o tal vez simplemente olvide que lo redirigió a un archivo. Más tarde entras y dices "bueno, que dice:

out.println("WE MADE IT"); 

pero no veo esa línea en la salida estándar, ¿qué diablos?"

Luego pasas 4 horas siguiendo una mala indicación en lugar de corregir el error.

+0

Si usaba Eclipse y vio 'afuera', ¿no presionaría F3 y vería exactamente hacia dónde iba sin perder tiempo? Estoy a favor de eliminar la duplicación y eliminar la llamada de System.out en todos los lugares donde se usa es eliminar la duplicación. Las razones están bien delineadas por la respuesta http://stackoverflow.com/questions/3041482/plain-old-system-out-question/3041495#3041495 – Alb

+0

No si no pensaste en eso, que es todo el punto. Explicación explícita de golpes cuando está trabajando con otros. Cuando estás solo, tu código puede ser tan divertido como quieras, pero me canso de trabajar en los trucos de otras personas. Esta actitud es recibir amor/odio con las convenciones de nomenclatura Java. Quiero decir, ahorrarías tanto espacio usando yalvn en lugar de escribir yetAnotherLongVariableName, pero algunas personas están comenzando a tener la importancia de explícito sobre breve (al menos en el mundo de Java, todavía veo una gran cantidad de variables "yalvn" c nombres, como si ocuparan memoria o algo así) –

+0

Claro que aprecio un nombre de método decente, pero en este caso el nombre del método original está simplemente 'fuera'. En primer lugar, no creo que nadie deba suponer que esto sería System.out sin comprobarlo, en segundo lugar, no creo que agregar el paquete en cada invocación sea la mejor manera de solucionarlo. Extraer todas las llamadas de System.out a, por ejemplo, el método 'printToConsole' o 'printToLogStream' es mejor que dejarlas en línea, en mi opinión, ya que elimina la duplicación pero mantiene la claridad de intención. – Alb

0

Si esta es una buena idea es discutible, y probablemente dependa de las circunstancias.

En el lado positivo:

  • Esto hace que el aspecto más ordenado código de la aplicación.
  • Puede simplificar cambiar el destino para la salida.

En el lado negativo:

  • Se aumenta potencialmente acoplamiento cruzado; p.ej. si la variable out es una variable de instancia o tiene que pasarse como un parámetro.
  • Posiblemente cause problemas si su aplicación necesita llamar al System.setOut().
  • Si el código System.out simplemente está depurando, esto hace que sea más difícil de detectar y eliminar. De hecho, probablemente anule los controles de calidad del código del PMD (etc.) que informan sobre este tipo de cosas.

Debe tenerse en cuenta que hay otras maneras potencialmente de hacerlo; p.ej. reemplazar System.out.println(String) con un método de utilidad printLine(String) logra un efecto similar sin el acoplamiento cruzado.

0

desde System.out es una variable final, lo que hizo sería identitcal a la referencia System.out directamente.

a menos que alguien llame al System.setOut() que reasignó System.out.

espera, ¿qué?

1

Puede ser que, en general, no se recomienda profundizar y utilizar objetos que sean miembros de otros objetos. Se ve como alguien que busca su bolsillo para sacar su dinero de su billetera en lugar de pedirle que le preste algo de dinero.

Puede haber una ligera ventaja de esto que sería poder cambiar el flujo de salida si es necesario a un archivo, socket o lo que sea.Por lo que sería capaz de reemplazar:

PrintStream out = System.out; 

con

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

Sin embargo, si está declarando repetidamente una y otra vez que realmente está perdiendo la ventaja anterior, porque el objetivo sería tener está centralizado en algún lugar y decide dónde generar los registros en un solo lugar.

Tenga en cuenta que esta es una forma muy cruda y la práctica estándar real es utilizar el registro. Java tiene su propio paquete java.util.logging fuera de la caja, log4j es otra alternativa muy poderosa (y muy popular) y hay otros.

Cuestiones relacionadas