2011-01-18 16 views
10

Esta es una pregunta de estilo de código. Me he dado cuenta mucho código de ejemplo incluidos algunos examples from Oracle asegurar que una corriente se cierra de la siguiente manera:Estilo de código Java para secuencia abierta try/finally block

InputStream in = null; 
try { 
    in = acquireStream(); 
    ... 
} finally { 
    if (in != null) in.close(); 
} 

Nota a la inicialización nulo y comprobar NULL en el bloque finally.

tiendo a escribir código como este:

InputStream in = acquireStream(); 
try { 
    ... 
} finally { 
    in.close(); 
} 

¿Hay ventajas o desventajas de uno u otro enfoque? Me gusta mi estilo porque no necesito el cheque nulo. También me gusta evitar null cuando sea posible. Pero dado que el estilo de Oracle es tan común en los ejemplos en línea, me pregunto si el mío tiene algún error oculto.

me hacen la misma pregunta para InputStream, OutputStream, java.sql.Connection, java.sql.PreparedStatement, etc. tiendo a adquirió el recurso fuera del bloque try y cierre en finally sin un cheque nulo. ¿Hay algo que me falta aparte de las diferencias de estilo?

Gracias.

Respuesta

3

Normalmente lo que tienes es try, catch, finally. En ese caso, es ventajoso utilizar el enfoque estándar de SUN porque puede capturar cualquier error que ocurra en acquireStream() dentro de try, catch.

0

Si su acquireStream() devolvió nulo, obtendrá NPE cuando intente cerrar la secuencia en el bloque finally y no se detectará.

0

Yo soy el primero. Algunos operadores de E/S requieren que estén dentro de un try/catch para alguna condición u otra. Además, las operaciones siempre pueden devolver el nulo inesperadamente, aunque no esté en el manual.

3

me gustaría utilizar

InputStream in = null; 
try { 
    in = acquireStream(); 
    ... 
} finally { 
    if (in != null) in.close(); 
} 

si aquireStream() tiros ninguna excepción revisada y tengo la intención de manejar la situación.

Si no, voy a utilizar este

InputStream in = acquireStream(); 
try { 
    ... 
} finally { 
    in.close(); 
} 

en NPE:

yo preferiría dejar que la NPE para propagar y no manejar cualquier excepción en tiempo de ejecución.

2

Creo que es más seguro adquirir la transmisión dentro del bloque de prueba.

Hay otra opción para el cierre - en lugar de la comprobación de nulos se puede hacer lo siguiente:

finally { 
    IOUtils.closeQuietly(in); 
} 

Esto requiere Apache Commons-IO para hacer esto, pero lo hará el cheque nulo para usted. También es una buena forma estilística para hacer esto.

+0

Ver: http://commons.apache.org/io/api-release/org/apache/commons/io/IOUtils.html#closeQuietly(java.io.InputStream) – Jon

0

lo general do this:

InputStream in = null; 
try { 
    in = acquire(); 
    ... 
} finally { 
    if(in != null) try { 
     in.close(); 
    } catch(IOException ioe) { 
     // ignore exception while closing 
    } 
} 

Mientras se cierra el recurso, una excepción se puede producir, en cuyo caso se necesitará un try/catch extra, pero la mayoría de las veces que está bien para mí hacer caso omiso (lo estoy cerrando después de todo) pero este es el único lugar donde utilizo si no tiene llaves.

Vi esto desde Huckstercode hace mucho tiempo.

+0

Compila realmente (sin tener en cuenta un valor declarado) , si es improbable en este caso, excepción). –

+0

Referencia de 'in' que no está definitivamente asignado en la cláusula' finally'. –

+0

@Tom, tienes toda la razón. Me confundí con el: 'Objeto o; if (cond) {o = algo; } else {o = algo intrínseco; } 'modismo. ¡Fijo! – OscarRyz

5

La respuesta es, no, no hay un error oculto al hacerlo a su manera. Es puramente una cosa de estilo. Normalmente nunca tengo un bloque try try finally, solo trato de atrapar bloques y probar finalmente los bloques.

tienden a terminar pareciéndose a esto:

try { 
    InputStream in = acquireStream(); 
    try { 
     ... 
    } finally { 
     in.close(); 
    } 
} catch (IOException e) { 
    ... handle exception 
} 

No hay ninguna razón para poner acquireStream() en el intento bloque finally. Si nunca se asigna a una transmisión válida, nunca se puede cerrar. Una verificación nula explícita es totalmente innecesaria. Además, es raro que desee manejar una excepción en el cierre() de forma diferente a una excepción en el bloque de procesamiento principal.

+0

me gusta esta solución – wutzebaer

8

Desde Java 7 hay una manera mucho más agradable para escribir try-finally en lo que respecta a los recursos Closeable.

Ahora usted puede crear sus recursos entre paréntesis después de la palabra clave try, así:

try (init resources) { 
    ... 
} 

Y se cerrará automcatically después de que el bloque de código está terminado. No es necesario cerrar las transmisiones en el bloque finally.

Un ejemplo:

try (
    ZipFile zf = new ZipFile(zipFileName); 
    BufferedWriter writer = Files.newBufferedWriter(outputFilePath, charset); 
) { 
    // Enumerate each entry 
    for (Enumeration entries = zf.entries(); entries.hasMoreElements();) { 
     // Get the entry name and write it to the output file 
     String newLine = System.getProperty("line.separator"); 
     String zipEntryName = ((java.util.zip.ZipEntry)entries.nextElement()).getName() + newLine; 
     writer.write(zipEntryName, 0, zipEntryName.length()); 
    } 
} 

Y después del bucle for se hace, se cerrarán los recursos!

+0

gracias! Es una buena práctica manejar objetos obturables. –

Cuestiones relacionadas