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 catchclá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

catchde 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
catchcláusula. Oracle java 7 doc dice que el recurso se cerrará independientemente de si se lanza una excepción o no.Debe usar una
catchcláusula solo si desea reaccionar ante la excepción. Lacatchclá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
catchy luego elfinallybloque. Esto hace que los recursos todavía estén potencialmente abiertos en elcatchbloque.En la sintaxis de Java 7, los recursos se cierran antes del
catchbloque, por lo que los recursos ya están cerrados durante lacatchejecució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ó
szsiendo 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
brfallasfiletodavía se cierra. Puede encontrar más detalles aquí y aquí .fuente
new FileReader(filePath))no se cerraría en caso de queIllegalArgumentExceptionse lanzara un cuando sz es negativo. ¿No cierra el try-with-resources todos losAutoClosablerecursos 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 < 0hace que el constructor arroje una excepción de hecho hará que el recurso se filtre.