Patrón Try With Resources
Parte de la sección Programación Orientada a Objetos del Journey de Java de Coddy. Lección 62 de 87.
Al trabajar con recursos como flujos de archivos o conexiones de base de datos, siempre debes cerrarlos al terminar. De lo contrario, te arriesgas a sufrir fugas de memoria. El enfoque tradicional utiliza un bloque finally, pero es verboso y propenso a errores.
La instrucción try-with-resources de Java cierra automáticamente los recursos cuando se completa el bloque. Cualquier clase que implemente la interfaz AutoCloseable puede usarse con esta sintaxis:
// Enfoque tradicional - verboso y arriesgado
BufferedReader reader = null;
try {
reader = new BufferedReader(new FileReader("file.txt"));
String line = reader.readLine();
} finally {
if (reader != null) {
reader.close(); // ¡También podría lanzar una excepción!
}
}
// Try-with-resources - limpio y seguro
try (BufferedReader reader = new BufferedReader(new FileReader("file.txt"))) {
String line = reader.readLine();
} // Se cierra automáticamente aquíPuedes gestionar varios recursos separándolos con punto y coma. Se cierran en el orden inverso al de su declaración:
try (FileReader fr = new FileReader("input.txt");
BufferedReader br = new BufferedReader(fr)) {
// Usa ambos recursos
} // br se cierra primero, luego frPara crear tu propia clase auto-cerrable, implementa la interfaz AutoCloseable y su único método close():
public class DatabaseConnection implements AutoCloseable {
public DatabaseConnection() {
System.out.println("Connection opened");
}
@Override
public void close() {
System.out.println("Connection closed");
}
}Este patrón garantiza que los recursos se liberen siempre correctamente, incluso si se producen excepciones durante el procesamiento.
Desafío
Fácil¡Construyamos un sistema de gestión de recursos que demuestre el poder de try-with-resources! Crearás clases autocerrables personalizadas que simulan la gestión de conexiones y sesiones, asegurándote de que siempre se limpien correctamente.
Organizarás tu código en tres archivos:
Connection.java: Crea una clase que simule una conexión a una base de datos. Tu claseConnectiondebe implementarAutoCloseable. Necesita un campo privado para el nombre de la conexión (String), un constructor que reciba el nombre e imprima[name] connection opened, un métodoquery(String sql)que imprimaExecuting on [name]: [sql]y el método requeridoclose()que imprima[name] connection closed.Session.java: Crea otra clase autocerrable que simule una sesión de usuario. Tu claseSessiontambién debe implementarAutoCloseable. Incluye un campo privado para el nombre de usuario (String), un constructor que reciba el nombre de usuario e imprimaSession started for [username], un métodoperformAction(String action)que imprima[username] performed: [action]y un métodoclose()que imprimaSession ended for [username].Main.java: ¡Reúne tu sistema de gestión de recursos! Recibirás tres entradas: un nombre de conexión, un nombre de usuario y una acción que realizarás.Primero, demuestra la gestión de un solo recurso. Imprime
=== Single Resource ===; después, usa try-with-resources para crear unaConnectioncon el nombre proporcionado. Dentro del bloque try, llama aquery("SELECT * FROM users"). La conexión debería cerrarse automáticamente cuando termine el bloque.A continuación, demuestra el uso de varios recursos. Imprime una línea en blanco y después
=== Multiple Resources ===. Usa try-with-resources con unaConnection(usando el mismo nombre) y unaSession(usando el nombre de usuario), declaradas en ese orden y separadas por punto y coma. Dentro del bloque try, llama primero aquery("INSERT INTO logs")en la conexión y después llama aperformActioncon la acción de entrada en la sesión. ¡Observa cómo los recursos se cierran en orden inverso!
Recibirás tres entradas en orden: nombre de conexión (String), nombre de usuario (String) y acción (String).
Observa cómo try-with-resources elimina la necesidad de realizar llamadas explícitas a close y de usar bloques finally. Se garantiza que los recursos se cierren incluso si se producen excepciones, y varios recursos se cierran en orden inverso al de su declaración.
Pruébalo tú mismo
import java.util.Scanner;
class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
String connectionName = scanner.nextLine();
String username = scanner.nextLine();
String action = scanner.nextLine();
// === Single Resource ===
// TODO: Imprime el encabezado
// TODO: Usa try-with-resources para crear un Connection
// TODO: Inside the try block, call query("SELECT * FROM users")
// === Multiple Resources ===
// TODO: Imprime una línea en blanco y el encabezado
// TODO: Usa try-with-resources con Connection y Session
// TODO: Dentro del bloque try:
// - Call query("INSERT INTO logs") on the connection
// - Llama a performAction con la action de entrada en el session
}
}
Esta lección incluye un breve cuestionario. Empieza la lección para responderlo y registrar tu progreso.
Todas las lecciones de Programación Orientada a Objetos
1Fundamentos de OOP
Archivos externosIntroducción a la OOPClases vs. ObjetosLa palabra clave thisMétodosCampos (Atributos)Método constructorSobrecarga de constructoresResumen - Calculadora simple4Herencia
Herencia básica (extends)La palabra clave superSobrescritura de métodos (@Override)Encadenamiento de constructoresLa clase ObjectHerencia simple y multinivelPor qué no hay herencia múltiple de clasesResumen - Jerarquía de empleados7Métodos especiales y la clase Object
Método toString()equals() y hashCode()Método clone()compareTo() y ComparableInterfaz ComparatorResumen - Ordenamiento personalizado10Manejo de excepciones en POO
Jerarquía de clases de excepcionesExcepciones personalizadasErrores Checked vs UncheckedPatrón Try With ResourcesResumen - Usuario validado2Modificadores de acceso y encapsulamiento
Visión general de los niveles de accesoMétodos Getter y SetterOcultamiento de informaciónLa palabra clave finalResumen - Gestor de cuentas bancarias5Polimorfismo
Fundamentos de sobrecarga de métodosSobrescritura de métodos (tiempo de ejecución)Upcasting y DowncastingEl operador instanceofClases y métodos abstractosResumen - Calculadora de figuras8Conceptos avanzados de POO
Composición vs. HerenciaAgregación vs. ComposiciónClases internas, anidadas y anónimasEnums y métodos de EnumRecords (Java 16+)Clases selladas (Java 17+)11Patrones de diseño - Parte 1
Introducción a los patrones de diseñoPatrón SingletonPatrón FactoryPatrón BuilderPatrón ObserverPatrón Strategy3Propiedades de clase y miembros estáticos
Variables de instancia vs. estáticasMétodos estáticosBloques estáticosConstantes (static final)Repaso - Contador y utilidad6Interfaces y Clases Abstractas
Introducción a las InterfacesImplementación de InterfacesImplementación de Múltiples InterfacesMétodos Default y Static en InterfacesClases Abstractas vs InterfacesInterfaces FuncionalesResumen - Sistema de Pagos9Genéricos
Introducción a los genéricosClases genéricasMétodos genéricosParámetros de tipo delimitadosComodines (?, extends, super)Resumen - Contenedor genérico12Patrones de diseño Parte 2
Patrón CommandPatrón AdapterPatrón DecoratorPatrón Template MethodPatrón StatePatrón CompositePatrón IteratorPractica por tu cuenta: Compilador de Java online