Pattern try-with-resources
Fa parte della sezione Programmazione orientata agli oggetti del percorso Java di Coddy. Lezione 62 di 87.
Quando lavori con risorse come flussi di file o connessioni al database, devi sempre chiuderle quando hai finito. Altrimenti rischi perdite di memoria. L’approccio tradizionale usa un blocco finally, ma è prolisso e soggetto a errori.
L’istruzione try-with-resources di Java chiude automaticamente le risorse al termine del blocco. Qualsiasi classe che implementi l’interfaccia AutoCloseable può essere usata con questa sintassi:
// Approccio tradizionale - prolisso e rischioso
BufferedReader reader = null;
try {
reader = new BufferedReader(new FileReader("file.txt"));
String line = reader.readLine();
} finally {
if (reader != null) {
reader.close(); // Potrebbe anche generare un'eccezione!
}
}
// Try-with-resources - semplice e sicuro
try (BufferedReader reader = new BufferedReader(new FileReader("file.txt"))) {
String line = reader.readLine();
} // Chiuso automaticamente quiPuoi gestire più risorse separandole con punti e virgola. Vengono chiuse in ordine inverso rispetto alla dichiarazione:
try (FileReader fr = new FileReader("input.txt");
BufferedReader br = new BufferedReader(fr)) {
// Usa entrambe le risorse
} // br viene chiuso per primo, poi frPer creare una tua classe con chiusura automatica, implementa l'interfaccia AutoCloseable e il suo unico metodo close():
public class DatabaseConnection implements AutoCloseable {
public DatabaseConnection() {
System.out.println("Connection opened");
}
@Override
public void close() {
System.out.println("Connection closed");
}
}Questo schema garantisce che le risorse vengano sempre rilasciate correttamente, anche se si verificano eccezioni durante l'elaborazione.
Sfida
FacileCostruiamo un sistema di gestione delle risorse che dimostri la potenza di try-with-resources! Creerai classi personalizzate chiudibili automaticamente che simulano la gestione di connessioni e sessioni, assicurandoti che vengano sempre chiuse correttamente.
Organizzerai il codice in tre file:
Connection.java: Crea una classe che simuli una connessione a un database. La tua classeConnectiondeve implementareAutoCloseable. Deve avere un campo privato per il nome della connessione (String), un costruttore che accetta il nome e stampa[name] connection opened, un metodoquery(String sql)che stampaExecuting on [name]: [sql]e il metodo richiestoclose()che stampa[name] connection closed.Session.java: Crea un'altra classe chiudibile automaticamente che simuli una sessione utente. Anche la tua classeSessiondeve implementareAutoCloseable. Includi un campo privato per il nome utente (String), un costruttore che accetta il nome utente e stampaSession started for [username], un metodoperformAction(String action)che stampa[username] performed: [action]e un metodoclose()che stampaSession ended for [username].Main.java: Metti insieme il tuo sistema di gestione delle risorse! Riceverai tre input: un nome di connessione, un nome utente e un'azione da eseguire.Per prima cosa, mostra la gestione di una singola risorsa. Stampa
=== Single Resource ===, quindi usa try-with-resources per creare unaConnectioncon il nome fornito. All'interno del blocco try, chiamaquery("SELECT * FROM users"). La connessione dovrebbe chiudersi automaticamente al termine del blocco.Successivamente, mostra la gestione di più risorse. Stampa una riga vuota, quindi
=== Multiple Resources ===. Usa try-with-resources con unaConnection(usando lo stesso nome) e unaSession(usando il nome utente), dichiarate in quest'ordine e separate da punti e virgola. All'interno del blocco try, chiama primaquery("INSERT INTO logs")sulla connessione, quindi chiamaperformActionsulla sessione usando l'azione inserita. Osserva come le risorse si chiudono in ordine inverso!
Riceverai tre input in quest'ordine: nome della connessione (String), nome utente (String) e azione (String).
Nota come try-with-resources elimina la necessità di chiamare esplicitamente close e di usare blocchi finally. È garantito che le risorse vengano chiuse anche se si verificano eccezioni, e le risorse multiple si chiudono in ordine inverso rispetto a quello della dichiarazione!
Provalo tu
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: Stampa l'intestazione
// TODO: Usa try-with-resources per creare una Connection
// TODO: All'interno del blocco try, chiama query("SELECT * FROM users")
// === Multiple Resources ===
// TODO: Stampa una riga vuota e l'intestazione
// TODO: Usa try-with-resources sia con Connection sia con Session
// TODO: All'interno del blocco try:
// - Chiama query("INSERT INTO logs") sulla connessione
// - Chiama performAction sulla sessione passando l'azione ricevuta in input
}
}
Questa lezione include un breve quiz. Inizia la lezione per rispondere e tenere traccia dei tuoi progressi.
Tutte le lezioni di Programmazione orientata agli oggetti
1Fondamenti della programmazione a oggetti
File esterniIntroduzione alla programmazione a oggettiClassi e oggettiLa parola chiave thisMetodiCampi (attributi)Metodo costruttoreSovraccarico dei costruttoriRipasso - Calcolatrice semplice4Ereditarietà
Ereditarietà di base (extends)La parola chiave superSovrascrittura dei metodi (@Override)Concatenamento dei costruttoriLa classe ObjectEreditarietà singola e multilivelloPerché non esiste l'ereditarietà multipla delle classiRiepilogo: gerarchia dei dipendenti7Metodi speciali e classe Object
Metodo toString()equals() e hashCode()Metodo clone()compareTo() e ComparableInterfaccia ComparatorRiepilogo - Ordinamento personalizzato10Gestione delle eccezioni in OOP
Gerarchia delle classi di eccezioneEccezioni personalizzateEccezioni controllate e non controllatePattern try-with-resourcesRiepilogo - Utente validato2Modificatori di accesso e incapsulamento
Panoramica dei livelli di accessoMetodi getter e setterNascondimento delle informazioniLa parola chiave finalRiepilogo - Gestore di conti bancari5Polimorfismo
Nozioni di base sull'overloading dei metodiOverride dei metodi (a runtime)Upcasting e downcastingL'operatore instanceofClassi e metodi astrattiRiepilogo - Calcolatore di forme8Concetti avanzati di OOP
Composizione vs ereditarietàAggregazione vs composizioneClassi interne, annidate e anonimeEnum e metodi degli EnumRecord (Java 16+)Classi sealed (Java 17+)11Modelli di progettazione Parte 1
Introduzione ai modelli di progettazionePattern SingletonPattern FactoryPattern BuilderPattern ObserverPattern Strategy3Proprietà di classe e membri statici
Variabili di istanza e staticheMetodi staticiBlocchi staticiCostanti (static final)Riepilogo - Contatore e utility6Interfacce e classi astratte
Introduzione alle interfacceImplementazione delle interfacceImplementazione di più interfacceMetodi default e static nelle interfacceClassi astratte e interfacce a confrontoInterfacce funzionaliRiepilogo: sistema di pagamento9Tipi generici
Introduzione ai tipi genericiClassi genericheMetodi genericiParametri di tipo con limitiCaratteri jolly (?, extends, super)Riepilogo - Contenitore generico12Modelli di progettazione – Parte 2
Pattern CommandPattern AdapterPattern DecoratorPattern Template MethodPattern StatePattern CompositePattern IteratorEsercitati da solo: Compilatore Java online