Metoda finalize, interfața care se poate închide și declarația de încercare cu resurse (Java 7) - 1

"Bună, Amigo!"

„Tocmai am decis să discut despre metoda finalize () cu tine.”

„Dacă vă amintiți, finalize() este o metodă specială care este apelată de un obiect înainte ca colectorul de gunoi să-l distrugă.”

„Scopul principal al acestei metode este de a elibera resurse externe non-Java utilizate prin închiderea fișierelor, fluxurilor I/O și așa mai departe.”

„Din păcate, această metodă nu se ridică la înălțimea așteptărilor noastre. Mașina virtuală Java poate amâna distrugerea unui obiect, precum și apelarea metodei finalize, atâta timp cât dorește. În plus, nu garantează că această metodă va fi apelat deloc. Există o mulțime de situații în care nu este apelat, totul în numele „optimizării”."

„Am două referințe pentru tine:”

Joshua Bloch a scris un articol bun despre această metodă: link
Voi parafraza un scurt fragment:

  1. finalize() poate fi folosit doar în două cazuri:
    1. Pentru verificarea sau curățarea resurselor cu logare.
    2. Când lucrați cu cod nativ care nu este critic pentru scurgerile de resurse.
  2. finalize() face ca GC de 430 de ori mai lent la curățarea obiectelor
  3. finalize() ar putea să nu fie apelat
Dacă aș spune într-un interviu că finalize este o cârjă dăunătoare și periculoasă a cărei însăși existență este confuză, aș avea dreptate?

— Ei bine, asta mi-a făcut ziua, Ellie.

„Java 7 are o nouă declarație pentru a înlocui metoda finalize . Se numește try-with-resources . Nu este cu adevărat un înlocuitor pentru finalize , mai degrabă este o abordare alternativă.”

„Este ca un try-catch, dar cu resurse?”

„Este aproape ca try-catch . Lucrurile sunt, spre deosebire de metoda finalize (), blocul final într-o instrucțiune try- catch-finally este întotdeauna executat. Programatorii au folosit și această tehnică atunci când au avut nevoie să elibereze resurse, închideți fire etc.

„Iată un exemplu:”

InputStream is = null;
try
{
 is = new FileInputStream("c:/file.txt");
 is.read(…);
}
finally
{
 if (is != null)
 is.close();
}

„Indiferent dacă blocul try a fost executat corect sau a existat o excepție, blocul final va fi apelat întotdeauna și este posibil să eliberați resursele ocupate acolo.”

„Deci, în Java 7, a fost luată decizia de a oficializa această abordare, astfel:”

try(InputStream is = new FileInputStream("c:/file.txt"))
{
 is.read(…);
}

„Această declarație specială de încercare se numește try-with-resources (similar cu modul în care colecțiile au o alternativă pentru call foreach ).”

„Rețineți că după încercare există paranteze în care sunt declarate variabile și sunt create obiecte. Aceste obiecte pot fi folosite în interiorul blocului de încercare indicat de paranteze. Când blocul de încercare este executat, indiferent dacă s-a încheiat normal sau acolo a fost o excepție, metoda close() va fi apelată pentru orice obiecte create în paranteze."

"Ce interesant! Această notație este mult mai compactă decât cea anterioară. Nu sunt sigur că am înțeles-o încă."

„Nu este atât de greu pe cât crezi.”

„Deci, pot specifica clasa fiecărui obiect în paranteze?”

— Da, desigur, altfel parantezele ar fi de prea puţin folos.

„Și dacă trebuie să apelez la altă metodă după ce ies din blocul de încercare, unde o pun?”

„Lucrurile sunt puțin mai subtile aici. Java 7 introduce următoarea interfață:”

public interface AutoCloseable
{
 void close() throws Exception;
}

„Clasa dumneavoastră poate implementa această interfață. Și apoi puteți utiliza obiectele sale în interiorul unei instrucțiuni de încercare cu resurse. Numai astfel de obiecte pot fi create în parantezele unei instrucțiuni de încercare cu resurse pentru „închidere automată”.”

„Cu alte cuvinte, trebuie să suprascriu metoda close și să scriu cod în ea pentru a „curăța” obiectul meu și nu pot specifica o altă metodă?”

"Da. Dar puteți specifica mai multe obiecte - doar separați-le cu un punct și virgulă:"

try(
InputStream is = new FileInputStream("c:/file.txt");
OutputStream os = new FileOutputStream("c:/output.txt")
)
{
 is.read(…);
 os.write(…);
}

„Așa e mai bine, dar nu atât de cool pe cât am sperat”.

"Nu e chiar atât de rău. Te vei obișnui. Cu timpul."