Troels Arvin skrev
> Hvor "står" det egentlig - altså at man ikke manuelt må kalde
> finalize()? Hvilke problemer opstår ved at kalde den manuelt, fx. inden
> objektreferencen sættes til null?
Der er mig bekendt ikke noget i specifikation af Java der siger man ikke må
selv må kalde finalize hvis man absolut gerne vil. Faktisk står der i Java
Language Specifiation, afsnit 12.6: "A finalizer may be invoked explicitly,
just like any other method." Bruger man finalizer er det dog op til en selv
at kode den så den opfører sig korrekt selvom den bliver kaldt flere gange,
hvad enten det så er garbage collectoren eller programmet selv der kalder.
Læs selv mere om finalizers i JLS:
http://java.sun.com/docs/books/jls/second_edition/html/execution.doc.html#44760
> Jeg synes, at det er en ubetagelig gotcha ved Java, at man ikke kan være
> sikker på, at finalize() bliver kaldt. Se fx. følgende program. Efter
> afvikling findes hos mig 28 filer tilbage i "testdir" kataloget, med
> mindre jeg tilføjer System.gc() kaldet.
Finalize mekanismen har den uheldige egenskab, at folk ofte misforstår dens
anvendelse og bruger den som destructor i stedet, ofte med skuffende
resultat. Garbage collection er grundlæggende set en ikke deterministisk
process i Java der bruges til at genskabe ledig plads på heapen, så kald til
finalize er grundlæggende set også ikke-deterministisk.
Selvom der i dokumentationen for finalize står, at finalize kan bruges til
management af externe resourcer, så tror jeg man gør sig selv en tjeneste
ved som tommefingerregel aldrig at bruge finalize til dette, hvilket mig
bekendt også er den praksis Sun selv anbefaler. I stedet kan man (i Java
1.3+) lave en resource manager der benytter svage referencer og en shutdown
hook (Runtime.addShutdownHook), eller man kan benytte de oprydnings metoder
der allerede måtte være i de forskellige API'er.
I den kode du angiver kan du fx. benytte File.deleteOnExit et passende sted
under initializing af hver fil og så helt droppe finalize metoden og kaldet
til System.gc().
> Er der nogen, der kender til baggrunden for, at garbage-collector ikke
> per default køres til ende ved programafvikling? - Det burde vel
> sjældent være det store problem, hvis program-afvikling tager et par
> sekunder.
Med Runtime.runFinalizersOnExit (der nu er deprecated) kan man faktisk godt
bede JVM'en om at køre GC inden den afslutter, men som sagt bør ens kode
ikke være afhængig af dette. Faktisk burde det være sådan, at koden i
princippet også virker hvis den køres på en JVM med "uendelig" heap uden
garbage collection.
Mvh,
--
Filip Larsen