Padrão Try With Resources
Parte da seção Programação Orientada a Objetos do Journey de Java da Coddy — lição 62 de 87.
Ao trabalhar com recursos como fluxos de arquivos ou conexões de banco de dados, você deve sempre fechá-los quando terminar — caso contrário, corre o risco de vazamentos de memória. A abordagem tradicional usa um bloco finally, mas é verbosa e propensa a erros.
A instrução try-with-resources do Java fecha automaticamente os recursos quando o bloco é concluído. Qualquer classe que implemente a interface AutoCloseable pode ser usada com esta sintaxe:
// Abordagem tradicional - verbosa e arriscada
BufferedReader reader = null;
try {
reader = new BufferedReader(new FileReader("file.txt"));
String line = reader.readLine();
} finally {
if (reader != null) {
reader.close(); // Também pode lançar uma exceção!
}
}
// Try-with-resources - limpo e seguro
try (BufferedReader reader = new BufferedReader(new FileReader("file.txt"))) {
String line = reader.readLine();
} // Fechado automaticamente aquiVocê pode gerenciar múltiplos recursos separando-os com pontos e vírgulas. Eles são fechados na ordem inversa da declaração:
try (FileReader fr = new FileReader("input.txt");
BufferedReader br = new BufferedReader(fr)) {
// Use ambos os recursos
} // br fechado primeiro, depois frPara criar sua própria classe auto-closeable, implemente a interface AutoCloseable e seu ú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 padrão garante que os recursos sejam sempre liberados adequadamente, mesmo que ocorram exceções durante o processamento.
Desafio
FácilVamos construir um sistema de gerenciamento de recursos que demonstra o poder do try-with-resources! Você criará classes auto-closeable personalizadas que simulam o gerenciamento de conexões e sessões, garantindo que elas sejam sempre limpas adequadamente.
Você organizará seu código em três arquivos:
Connection.java: Crie uma classe que simule uma conexão de banco de dados. Sua classeConnectiondeve implementarAutoCloseable. Ela precisa de um campo privado para o nome da conexão (String), um construtor que recebe o nome e imprime[name] connection opened, um métodoquery(String sql)que imprimeExecuting on [name]: [sql], e o métodoclose()obrigatório que imprime[name] connection closed.Session.java: Crie outra classe auto-closeable que simule uma sessão de usuário. Sua classeSessiontambém deve implementarAutoCloseable. Inclua um campo privado para o nome de usuário (String), um construtor que recebe o nome de usuário e imprimeSession started for [username], um métodoperformAction(String action)que imprime[username] performed: [action], e um métodoclose()que imprimeSession ended for [username].Main.java: Reúna seu sistema de gerenciamento de recursos! Você receberá três entradas: um nome de conexão, um nome de usuário e uma ação a ser realizada.Primeiro, demonstre o gerenciamento de um único recurso. Imprima
=== Single Resource ===, então use try-with-resources para criar umaConnectioncom o nome fornecido. Dentro do bloco try, chamequery("SELECT * FROM users"). A conexão deve fechar automaticamente quando o bloco terminar.Em seguida, demonstre múltiplos recursos. Imprima uma linha em branco, depois
=== Multiple Resources ===. Use try-with-resources com umaConnection(usando o mesmo nome) e umaSession(usando o nome de usuário), declaradas nessa ordem com ponto e vírgula. Dentro do bloco try, primeiro chamequery("INSERT INTO logs")na conexão, depois chameperformActioncom a ação de entrada na sessão. Observe como os recursos fecham na ordem inversa!
Você receberá três entradas em ordem: nome da conexão (String), nome de usuário (String) e ação (String).
Observe como o try-with-resources elimina a necessidade de chamadas explícitas de fechamento e blocos finally. Os recursos têm o fechamento garantido mesmo se ocorrerem exceções, e múltiplos recursos fecham na ordem inversa da declaração!
Folha de consulta
A instrução try-with-resources fecha automaticamente os recursos quando o bloco é concluído. Qualquer classe que implemente AutoCloseable pode ser usada:
try (BufferedReader reader = new BufferedReader(new FileReader("file.txt"))) {
String line = reader.readLine();
} // Fechado automaticamente aquiMúltiplos recursos podem ser gerenciados separando-os com pontos e vírgulas. Eles fecham na ordem inversa da declaração:
try (FileReader fr = new FileReader("input.txt");
BufferedReader br = new BufferedReader(fr)) {
// Use ambos os recursos
} // br fechado primeiro, depois frPara criar uma classe auto-closeable personalizada, implemente a interface AutoCloseable e seu método close():
public class DatabaseConnection implements AutoCloseable {
public DatabaseConnection() {
System.out.println("Connection opened");
}
@Override
public void close() {
System.out.println("Connection closed");
}
}Experimente você mesmo
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();
// === Recurso Único ===
// TODO: Imprimir o cabeçalho
// TODO: Usar try-with-resources para criar uma Connection
// TODO: Dentro do bloco try, chamar query("SELECT * FROM users")
// === Múltiplos Recursos ===
// TODO: Imprimir uma linha em branco e o cabeçalho
// TODO: Usar try-with-resources com ambos Connection e Session
// TODO: Dentro do bloco try:
// - Chamar query("INSERT INTO logs") na conexão
// - Chamar performAction com a ação de entrada na sessão
}
}
Esta lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.
Todas as lições de Programação Orientada a Objetos
1Fundamentos de POO
Arquivos ExternosIntrodução à POOClasses vs ObjetosA Palavra-chave thisMétodosCampos (Atributos)Método ConstrutorSobrecarga de ConstrutorRecapitulação - Calculadora Simples4Herança
Herança Básica (extends)A Palavra-chave superSobrescrita de Método (@Override)Encadeamento de ConstrutoresA Classe ObjectHerança Simples e MultinívelPor que não há Herança Múltipla de ClassesRecapitulação - Hierarquia de Funcionários7Métodos Especiais e a Classe Object
Método toString()equals() e hashCode()Método clone()compareTo() e ComparableInterface ComparatorRecapitulação - Ordenação Personalizada10Tratamento de Exceções em POO
Hierarquia de Classes de ExceçãoExceções PersonalizadasErros Checked vs UncheckedPadrão Try With ResourcesRecapitulação - Usuário Validado2Modificadores de Acesso e Encapsulamento
Visão Geral dos Níveis de AcessoMétodos Getter e SetterOcultação de InformaçõesA Palavra-chave finalRecapitulação - Gerenciador de Conta Bancária5Polimorfismo
Fundamentos de Sobrecarga de MétodosSobrescrita de Métodos (Tempo de Execução)Upcasting e DowncastingO Operador instanceofClasses e Métodos AbstratosRecapitulação - Calculadora de Formas8Conceitos Avançados de OOP
Composição vs HerançaAgregação vs ComposiçãoClasses Internas, Aninhadas e AnônimasEnums e Métodos de EnumRecords (Java 16+)Classes Seladas (Java 17+)11Padrões de Projeto Parte 1
Introdução aos Padrões de ProjetoPadrão SingletonPadrão FactoryPadrão BuilderPadrão ObserverPadrão Strategy3Propriedades de Classe e Membros Estáticos
Variáveis de Instância vs EstáticasMétodos EstáticosBlocos EstáticosConstantes (static final)Recapitulação - Contador e Utilitário6Interfaces e Classes Abstratas
Introdução às InterfacesImplementando InterfacesImplementação de Múltiplas InterfacesDefault e Static em InterfacesClasses Abstratas vs InterfacesInterfaces FuncionaisRecapitulação - Sistema de Pagamento9Generics
Introdução a GenericsClasses GenéricasMétodos GenéricosParâmetros de Tipos DelimitadosWildcards (?, extends, super)Recapitulação - Container Genérico12Padrões de Projeto Parte 2
Padrão CommandPadrão AdapterPadrão DecoratorPadrão Template MethodPadrão StatePadrão CompositePadrão Iterator