De finalize-methode, de afsluitbare interface en de instructie 'try-with-resources' (Java 7) - 1

"Hallo Amigo!"

"Ik heb net besloten om de finalize () methode met je te bespreken."

"Als je het je herinnert, is finalize() een speciale methode die wordt aangeroepen door een object voordat de vuilnisman het vernietigt."

"Het belangrijkste doel van deze methode is om gebruikte externe niet-Java-bronnen vrij te maken door bestanden, I/O-streams, enzovoort te sluiten."

"Helaas voldoet deze methode niet aan onze verwachtingen. De virtuele Java-machine kan het vernietigen van een object uitstellen, evenals het aanroepen van de finalize-methode, zolang hij wil. Bovendien garandeert het niet dat deze methode zal worden helemaal niet gebeld. Er zijn tal van situaties waarin het niet wordt gebeld, allemaal in de naam van "optimalisatie".

"Ik heb twee referenties voor je:"

Joshua Bloch heeft een goed artikel geschreven over deze methode: link
Ik parafraseer een kort fragment:

  1. finalize() kan slechts in twee gevallen worden gebruikt:
    1. Voor het verifiëren of opschonen van bronnen met logboekregistratie.
    2. Bij het werken met native code die niet essentieel is voor het lekken van bronnen.
  2. finalize() maakt de GC 430 keer langzamer bij het opschonen van objecten
  3. finalize() wordt mogelijk niet aangeroepen
Als ik in een interview zeg dat finaliseren een schadelijke en gevaarlijke kruk is waarvan het bestaan ​​alleen al verwarrend is, zou ik dan gelijk hebben?

"Nou, dat maakte mijn dag goed, Ellie."

"Java 7 heeft een nieuwe verklaring om de finalize- methode te vervangen. Het heet try-with-resources . Het is niet echt een vervanging voor finalize , het is eerder een alternatieve benadering."

"Is het net als proberen te vangen, maar dan met middelen?"

"Het is bijna als try-catch . De dingen zijn dat, in tegenstelling tot de methode finalize (), het blok final in een instructie try- catch-finally altijd wordt uitgevoerd. Programmeurs hebben deze techniek ook gebruikt wanneer ze middelen moesten vrijmaken, threads sluiten, enz.

"Hier is een voorbeeld:"

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

"Ongeacht of het try- blok correct is uitgevoerd of dat er een uitzondering was, het final- blok wordt altijd aangeroepen en het is mogelijk om bezette bronnen daar vrij te geven."

"Dus in Java 7 werd de beslissing genomen om deze aanpak officieel te maken, zoals zo:"

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

"Deze speciale try- instructie wordt try-with-resources genoemd (vergelijkbaar met hoe collecties een alternatief hebben voor genaamd foreach )."

"Merk op dat er na de try haakjes zijn waar variabelen worden gedeclareerd en objecten worden gemaakt. Deze objecten kunnen worden gebruikt binnen het try-blok dat wordt aangegeven door de accolades. Wanneer het try-blok is uitgevoerd, ongeacht of het normaal is geëindigd of daar was een uitzondering, de methode close() wordt aangeroepen voor alle objecten die tussen haakjes zijn gemaakt."

'Wat interessant! Deze notatie is veel compacter dan de vorige. Ik weet niet zeker of ik hem al begrijp.'

"Het is niet zo moeilijk als je denkt."

"Dus, kan ik de klasse van elk object tussen haakjes specificeren?"

'Ja, natuurlijk, anders hebben de haakjes weinig nut.'

"En als ik een andere methode moet aanroepen nadat ik het try-blok heb verlaten, waar moet ik dat dan doen?"

"De dingen zijn hier wat subtieler. Java 7 introduceert de volgende interface:"

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

"Uw klas kan deze interface implementeren. En dan kunt u de objecten ervan gebruiken binnen een try-with-resources-instructie. Alleen dergelijke objecten kunnen worden gemaakt binnen de haakjes van een try-with-resources-instructie voor «automatische sluiting»."

"Met andere woorden, ik moet de sluitmethode overschrijven en er code in schrijven om mijn object te "opschonen", en ik kan geen andere methode specificeren?"

"Ja. Maar je kunt meerdere objecten specificeren - scheid ze gewoon met een puntkomma:"

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

"Dat is beter, maar niet zo cool als ik had gehoopt."

'Het is niet zo erg. Je zult er wel aan wennen. Na verloop van tijd.'