java - limpiar - commons io get extension
Cómo eliminar System.out.println''s de la base de código (8)
¿Has considerado editar esos archivos fuente para eliminar las líneas?
Es posible que solo un desarrollador demore un par de días y se deshaga de la mayoría de ellos. Tuvimos un problema similar y me levanté muy temprano y revisé todos nuestros archivos para deshacerse de la basura.
Usé Eclipse y la función de limpieza y guardado para limpiar importaciones y cosas al mismo tiempo.
¡Es una cosa bastante terapéutica!
Tenemos una gran base de código (antigua legacy java), donde muchos archivos (alrededor de 5k) tienen System.out.println. Estamos planeando eliminarlos por motivos de limpieza / rendimiento. ¿Cómo podemos escribir un script que los reemplace sin introducir ningún problema en el código? El script no puede eliminarlos ciegamente, ya que el siguiente caso puede ser un problema:
if ()
some.code...
else
System.out.println(...);
DB.close();
Estoy pensando en reemplazarlos por '';''. Eso se encargará del caso anterior. ¿Ves algún otro problema? ¿Cualquier otra sugerencia?
Escribí una expresión regular en Perl que reemplaza la cadena "System.out.println" con "; // System.out.println". Creo que hay muy pocos casos en que esto rompa la construcción. Simplemente se convertiría en un "else", que se compila con instrucciones de bytecode cero.
Parece que esto es lo que has propuesto. Me funcionó, excepto si tiene declaraciones adicionales en la misma línea. Sin embargo, ese es un estilo malo para empezar (y sabía que no lo hacía).
Extendiendo el concepto de Oscar puedes hacer aún mejor en mi humilde opinión:
if(!DEBUG) {
System.setOut(
new PrintStream(new OutputStream() {
public void close() {}
public void flush() {}
public void write(byte[] b) {}
public void write(byte[] b, int off, int len) {}
public void write(int b) {}
} );
}
}
En este caso, si no está en modo de depuración o en cualquier otro, el sistema predeterminado se reemplaza internamente con la implementación devNull, de lo contrario, funciona como se esperaba. De esta forma, no tiene que encontrar y reemplazar nada en su código.
Log4E es un complemento eclipse que tiene una función "Reemplazar System.out.println ()". Felizmente convertirá todas esas molestas llamadas println a las llamadas log4j. Incluso los envolverá con una verificación de nivel de registro.
Personalmente, usaría {}
, pero creo que funciona igual.
Puede comenzar llamando a Systems.setOut y pasando su propio OutputStream que no hace nada. Eso te ayudará a ver si hay una ganancia de rendimiento. Esto es más seguro que eliminarlos (por la razón que Oscar señaló, codificación por efecto secundario). Si la ganancia de rendimiento es insignificante, entonces es posible que desee centrar sus esfuerzos en otra parte.
Dos problemas con mi método anterior:
- cualquier System.out.printlns que quieras mantener desaparecerá también
- la concatenación de cadenas todavía tendrá lugar (y eso puede ser costoso dependiendo de cuánto hay)
Sin embargo, es una buena prueba rápida para ver si obtienes los aumentos de rendimiento que estás buscando.
¿Has considerado el estúpido caso?
System.out.println(" Print " + object.changeState() );
No creo que suceda, pero es probable que la impresora ejecute un método que realmente está llevando a cabo alguna acción de la que depende el sistema y puede introducir errores sutiles (créanme o no, pero he sido testigo de esto)
Probablemente reemplazar con un registrador y deshabilitar los registradores puede hacer.
O creando un objeto nulo usando el patrón NullObject:
public final class DevNull {
public final static PrintStream out = new PrintStream(new OutputStream() {
public void close() {}
public void flush() {}
public void write(byte[] b) {}
public void write(byte[] b, int off, int len) {}
public void write(int b) {}
} );
}
Y reemplazando
System.out.println();
Con
DevNull.out.println();
Puede usar una compilación condicional para tener una compilación de depuración con las instrucciones de impresión y una versión de lanzamiento sin ellas.
Básicamente, la idea es crear una clase estática final con un booleano estático final que utilice como un interruptor en tiempo de compilación.
public final class Debug {
//set to false to allow compiler to identify and eliminate
//unreachable code
public static final boolean ON = true;
}
Luego puede simplemente reemplazar todas sus declaraciones System.out.println
con
if(Debug.ON)
{
System.out.println...
}
Como el compilador ignorará las ramas de código inalcanzables, puede establecer ON = false
cuando realice una versión de lanzamiento y las instrucciones de impresión se excluirán de su bytecode.
Nota: Esto no se ocupa del caso que Oscar señaló, donde una declaración impresa puede cambiar el estado de algún objeto. Puede usar la compilación condicional para imprimir en un objeto nulo cuando está en modo de lanzamiento, como sugirió, en lugar de eliminar las copias por completo.