Espero que el lector de búfer y el lector de archivos se cierren y los recursos se liberen si se lanza la excepción.
public static Object[] fromFile(String filePath) throws FileNotFoundException, IOException
{
try (BufferedReader br = new BufferedReader(new FileReader(filePath)))
{
return read(br);
}
}
Sin embargo, ¿existe algún requisito para tener una catch
cláusula para un cierre exitoso?
EDITAR:
Esencialmente, el código anterior en Java 7 es equivalente al siguiente para Java 6:
public static Object[] fromFile(String filePath) throws FileNotFoundException, IOException
{
BufferedReader br = null;
try
{
br = new BufferedReader(new FileReader(filePath));
return read(br);
}
catch (Exception ex)
{
throw ex;
}
finally
{
try
{
if (br != null) br.close();
}
catch(Exception ex)
{
}
}
return null;
}
java-7
try-with-resources
leopardo
fuente
fuente
catch
de tu ejemplo para Java 6. Es decircatch (Exception ex) { throw ex; }
, simplemente está volviendo a lanzar la excepción, no hace nada, se puede eliminar fácilmente sin ningún daño. ¿O me estoy perdiendo algo?Respuestas:
Es correcto y no hay requisito de
catch
cláusula. Oracle java 7 doc dice que el recurso se cerrará independientemente de si se lanza una excepción o no.Debe usar una
catch
cláusula solo si desea reaccionar ante la excepción. Lacatch
cláusula se ejecutará después de que se cierre el recurso.Aquí hay un fragmento del tutorial de Oracle :
static String readFirstLineFromFile(String path) throws IOException { try (BufferedReader br = new BufferedReader(new FileReader(path))) { return br.readLine(); } } // In this example, the resource declared in the try-with-resources statement is a BufferedReader.
EDITAR
Con respecto a la nueva pregunta editada:
El código en Java 6 ejecuta el
catch
y luego elfinally
bloque. Esto hace que los recursos todavía estén potencialmente abiertos en elcatch
bloque.En la sintaxis de Java 7, los recursos se cierran antes del
catch
bloque, por lo que los recursos ya están cerrados durante lacatch
ejecución del bloque. Esto está documentado en el enlace anterior:fuente
El uso de try-with-resources funcionará bien en este caso particular, pero no es del todo correcto en general. No debe encadenar recursos como ese porque puede llevar a sorpresas desagradables. Suponga que tiene un tamaño de búfer variable:
public static Object[] fromFile(String filePath) throws FileNotFoundException, IOException { int sz = /* get buffer size somehow */ try (BufferedReader br = new BufferedReader(new FileReader(filePath), sz)) { return read(br); } }
Suponga que algo salió mal y terminó
sz
siendo negativo. En este caso, su recurso de archivo (creado mediantenew FileReader(filePath)
) NO se cerrará.Para evitar este problema, debe especificar cada recurso por separado de esta manera:
public static Object[] fromFile(String filePath) throws FileNotFoundException, IOException { int sz = /* get buffer size somehow */ try (FileReader file = new FileReader(filePath); BufferedReader br = new BufferedReader(file, sz)) { return read(br); } }
En este caso, incluso si la inicialización de
br
fallasfile
todavía se cierra. Puede encontrar más detalles aquí y aquí .fuente
new FileReader(filePath))
no se cerraría en caso de queIllegalArgumentException
se lanzara un cuando sz es negativo. ¿No cierra el try-with-resources todos losAutoClosable
recursos independientemente de las excepciones lanzadas?.close()
a las variables que se han declarado en el inicializador try-with-resources. Es por eso que separarlo en dos declaraciones en este ejemplo funciona.sz < 0
hace que el constructor arroje una excepción de hecho hará que el recurso se filtre.