En este tutorial, aprenderemos sobre la instrucción try-with-resources para cerrar recursos automáticamente.
La try-with-resources
declaración cierra automáticamente todos los recursos al final de la declaración. Un recurso es un objeto que se cerrará al final del programa.
Su sintaxis es:
try (resource declaration) ( // use of the resource ) catch (ExceptionType e1) ( // catch block )
Como se ve en la sintaxis anterior, declaramos la try-with-resources
declaración por,
- declarar y instanciar el recurso dentro de la
try
cláusula. - especificando y manejando todas las excepciones que podrían lanzarse al cerrar el recurso.
Nota: La declaración try-with-resources cierra todos los recursos que implementan la interfaz AutoCloseable.
Tomemos un ejemplo que implementa la try-with-resources
declaración.
Ejemplo 1: prueba con recursos
import java.io.*; class Main ( public static void main(String() args) ( String line; try(BufferedReader br = new BufferedReader(new FileReader("test.txt"))) ( while ((line = br.readLine()) != null) ( System.out.println("Line =>"+line); ) ) catch (IOException e) ( System.out.println("IOException in try block =>" + e.getMessage()); ) ) )
Salida si no se encuentra el archivo test.txt.
IOException en el bloque try-with-resources => test.txt (No existe tal archivo o directorio)
Salida si se encuentra el archivo test.txt.
Ingresando el bloque try-with-resources Line => línea de prueba
En este ejemplo, usamos una instancia de BufferedReader para leer datos del test.txt
archivo.
Declarar y crear instancias de BufferedReader dentro de la try-with-resources
declaración garantiza que su instancia se cierre independientemente de si la try
declaración se completa normalmente o lanza una excepción.
Si ocurre una excepción, puede manejarse usando los bloques de manejo de excepciones o la palabra clave throws.
Excepciones suprimidas
En el ejemplo anterior, se pueden lanzar excepciones desde la try-with-resources
declaración cuando:
test.txt
No se encuentra el archivo .- Cerrando el
BufferedReader
objeto.
También se puede lanzar una excepción del try
bloque, ya que la lectura de un archivo puede fallar por muchas razones en cualquier momento.
Si se lanzan excepciones tanto del try
bloque como de la try-with-resources
declaración, try
se lanza la excepción del bloque y try-with-resources
se suprime la excepción de la declaración.
Recuperar excepciones suprimidas
En Java 7 y versiones posteriores, las excepciones suprimidas se pueden recuperar llamando al Throwable.getSuppressed()
método desde la excepción lanzada por el try
bloque.
Este método devuelve una matriz de todas las excepciones suprimidas. Obtenemos las excepciones suprimidas en el catch
bloque.
catch(IOException e) ( System.out.println("Thrown exception=>" + e.getMessage()); Throwable() suppressedExceptions = e.getSuppressed(); for (int i=0; i" + suppressedExceptions(i)); ) )
Ventajas de usar try-with-resources
Estas son las ventajas de usar try-with-resources:
1. finalmente no es necesario bloquear para cerrar el recurso
Antes de que Java 7 introdujera esta función, teníamos que usar el finally
bloque para asegurarnos de que el recurso esté cerrado para evitar fugas de recursos.
Este es un programa que es similar al Ejemplo 1 . Sin embargo, en este programa, hemos usado finalmente bloquear para cerrar recursos.
Ejemplo 2: Cerrar recurso usando finalmente bloquear
import java.io.*; class Main ( public static void main(String() args) ( BufferedReader br = null; String line; try ( System.out.println("Entering try block"); br = new BufferedReader(new FileReader("test.txt")); while ((line = br.readLine()) != null) ( System.out.println("Line =>"+line); ) ) catch (IOException e) ( System.out.println("IOException in try block =>" + e.getMessage()); ) finally ( System.out.println("Entering finally block"); try ( if (br != null) ( br.close(); ) ) catch (IOException e) ( System.out.println("IOException in finally block =>"+e.getMessage()); ) ) ) )
Salida
Ingresando try block Line => línea del archivo test.txt Ingresando finalmente block
Como podemos ver en el ejemplo anterior, el uso de finally
block para limpiar recursos hace que el código sea más complejo.
¿Observa el try… catch
bloque en el finally
bloque también? Esto se debe a IOException
que también se puede producir un error al cerrar la BufferedReader
instancia dentro de este finally
bloque, por lo que también se detecta y gestiona.
La try-with-resources
declaración hace la gestión automática de recursos . No es necesario cerrar explícitamente los recursos ya que JVM los cierra automáticamente. Esto hace que el código sea más legible y más fácil de escribir.
2. probar con recursos con múltiples recursos
Podemos declarar más de un recurso en la try-with-resources
declaración separándolos con un punto y coma;
Ejemplo 3: pruebe con varios recursos
import java.io.*; import java.util.*; class Main ( public static void main(String() args) throws IOException( try (Scanner scanner = new Scanner(new File("testRead.txt")); PrintWriter writer = new PrintWriter(new File("testWrite.txt"))) ( while (scanner.hasNext()) ( writer.print(scanner.nextLine()); ) ) ) )
Si este programa se ejecuta sin generar ninguna excepción, el Scanner
objeto lee una línea del testRead.txt
archivo y la escribe en un nuevo testWrite.txt
archivo.
Cuando se realizan varias declaraciones, la try-with-resources
declaración cierra estos recursos en orden inverso. En este ejemplo, el PrintWriter
objeto se cierra primero y luego el Scanner
objeto se cierra.
Mejora de prueba con recursos de Java 9
En Java 7, existe una restricción a la try-with-resources
declaración. El recurso debe declararse localmente dentro de su bloque.
try (Scanner scanner = new Scanner(new File("testRead.txt"))) ( // code )
Si declaramos el recurso fuera del bloque en Java 7, habría generado un mensaje de error.
Scanner scanner = new Scanner(new File("testRead.txt")); try (scanner) ( // code )
Para lidiar con este error, Java 9 mejoró la try-with-resources
declaración para que la referencia del recurso se pueda usar incluso si no se declara localmente. El código anterior ahora se ejecutará sin ningún error de compilación.