Finaliseringsmetoden, lukbar grænseflade og prøv-med-ressourcer-erklæringen (Java 7) - 1

"Hej, Amigo!"

"Jeg har lige besluttet at diskutere færdiggørelsesmetoden ( ) med dig."

"Hvis du husker det, er finalize() en speciel metode, der kaldes af et objekt, før skraldesamleren ødelægger det."

"Denne metodes hovedformål er at frigøre brugte eksterne ikke-Java-ressourcer ved at lukke filer, I/O-streams og så videre."

"Desværre lever denne metode ikke op til vores forventninger. Den virtuelle Java-maskine kan udsætte at ødelægge et objekt, samt kalde finalize-metoden, så længe den vil. Desuden garanterer den ikke, at denne metode bliver kaldes overhovedet. Der er masser af situationer, hvor det ikke bliver kaldt, alt sammen i navnet "optimering"."

"Jeg har to referencer til dig:"

Joshua Bloch har skrevet en god artikel om denne metode: link
Jeg vil omskrive et kort uddrag:

  1. finalize() kan kun bruges i to tilfælde:
    1. Til verificering eller oprydning af ressourcer med logning.
    2. Når du arbejder med indbygget kode, som ikke er kritisk for ressourcelækager.
  2. finalize() gør GC'en 430 gange langsommere til at rydde op i objekter
  3. finalize() kaldes muligvis ikke
Hvis jeg i et interview siger, at finalize er en skadelig og farlig krykke, hvis eksistens er forvirrende, ville jeg så have ret?

"Nå, det gjorde min dag, Ellie."

"Java 7 har en ny erklæring til at erstatte færdiggørelsesmetoden . Det kaldes prøv-med-ressourcer . Det er egentlig ikke en erstatning for færdiggør , men det er en alternativ tilgang."

"Er det som try-catch, men med ressourcer?"

"Det er næsten som try-catch . Tingene er, i modsætning til finalize ()-metoden, at finally- blokken i en try- catch-finally- sætning altid udføres. Programmører har også brugt denne teknik, når de har haft brug for at frigøre ressourcer, luk tråde osv.

"Her er et eksempel:"

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

"Uanset om prøveblokken blev udført korrekt, eller der var en undtagelse, vil den endelige blok altid blive kaldt, og det er muligt at frigive besatte ressourcer der."

"Så i Java 7 blev beslutningen truffet om at gøre denne tilgang officiel, som sådan:"

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

"Denne specielle try- erklæring kaldes try-with-resources (svarende til hvordan samlinger har en alternativ til kaldet foreach )."

"Bemærk, at der efter forsøget er parenteser, hvor variabler erklæres og objekter oprettes. Disse objekter kan bruges inde i prøveblokken angivet med de krøllede parenteser. Når prøveblokken er færdig med at blive udført, uanset om den endte normalt eller der var en undtagelse, vil close()-metoden blive kaldt på alle objekter, der er oprettet inden for parentes."

"Hvor interessant! Denne notation er langt mere kompakt end den forrige. Jeg er ikke sikker på, jeg forstår den endnu."

"Det er ikke så svært, som du tror."

"Så, kan jeg angive klassen for hvert objekt i parentes?"

"Ja, selvfølgelig, ellers ville parentesen være til lidt nytte."

"Og hvis jeg skal kalde en anden metode efter at have afsluttet prøveblokken, hvor skal jeg så placere den?"

"Tingene er lidt mere subtile her. Java 7 introducerer følgende grænseflade:"

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

"Din klasse kan implementere denne grænseflade. Og så kan du bruge dens objekter i en try-with-resources-sætning. Kun sådanne objekter kan oprettes inden for parentesen af ​​en try-with-resources-sætning til «automatisk lukning»."

"Med andre ord, jeg er nødt til at tilsidesætte lukkemetoden og skrive kode i den for at "rydde op" i mit objekt, og jeg kan ikke angive en anden metode?"

"Jep. Men du kan angive flere objekter - bare adskille dem med et semikolon:"

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

"Det er bedre, men ikke så fedt, som jeg havde håbet."

"Det er ikke så slemt. Du vænner dig til det. Med tiden."