Peter, On 15 Oct 2015, at 09:12, Peter Levart <peter.lev...@gmail.com> wrote:
> On 10/14/2015 07:43 PM, Roger Riggs wrote: >> Hi Alan, Mandy, >> >> I looked at a few of the many uses of finalize and the likely changes. >> The zip Inflater and Deflater are relatively simple cases. >> Some finalizers are not used and can be removed. >> The sun.net.www.MeteredStream example subclasses PhantomCleanable to add the >> state and cleanup >> behavior. >> >> http://cr.openjdk.java.net/~rriggs/webrev-cleaning-finalizers/ >> >> Some of the harder cases will take more time to disentangle the cleanup code. >> For example, ZipFile, and FileIn/OutputStream (Peter has prototyped this). >> >> Roger > > Hi Roger, > > It's good to see some actual uses of the API and how it is supposed to be > used in migration from finalize() methods. I think empty protected finalize() > method is almost always safe to remove. If the class is not subclassed, it > serves no purpose (unless some other same-package class or itself is calling > it, which can be checked and those calls removed). If subclass overrides > finalize() and calls super.finalize(), its ok (it will call Object.finalize > then when empty finalize() is removed). The same holds if a subclass calls > finalize() as a virtual method regardless of whether it also overrides it or > not. > > One thing to watch for is in case a subclass overrides finalize() like this: > > class Subclass extends Superclass { > ... > @Override protected finalize() { > .... pre-actions ... > super.finalize(); > ... post-actions... > } > > ... where the order of cleanup actions has to be orchestrated between super > and subclass. Having a PhantomCleanable replace the finalize() in a > superclass has a similar effect as the following re-ordering in subclass: > > @Override protected finalize() { > .... pre-actions ... > ... post-actions... > super.finalize(); > } > > ...since finalization is performed before PhantomReference is enqueued. This > re-ordering is luckily often safe as post-actions usually can't use > superclass resources any more and usually don't depend on the state of > superclass. In addition, when superclass actions do happen, they can't invoke > any instance methods if they are refactored to use Cleaner. > > This brings up an interesting question. finalize() method allows subclasses > to override it and augment cleanup logic to include any state changes or > resources used by subclass. Or for a subclass to effectively cancel any clean up, by providing an empty finalize() method. Which I think is also supported by your proposal, or at least a side-effect of having the Cleanup as a protected field ( you can call clear on it, right? ). Having the Cleanup as a protected field looks a little odd, but no more so than the public/protected finalize method. This is now getting even more complicated. There are potentially multiple object references being tracked as part of the cleanup of a single “significant” object ? -Chris. > How about Cleanup API? Subclass can register it's own Cleanable for own > resources, but order of execution of superclass and subclass Cleanable(s) is > arbitrary then. Cleanables will often be established in constructors and > super/subclass constructors have a defined order of execution. So what about > the following: > > public class Cleaner { > > public Cleanup phantomCleanup(Object referent); > > public interface Cleanable { > void clean(); > void clear(); > } > > public interface Cleanup extends Cleanable { > Cleanable append(Runnable action); > Cleanable prepend(Runnable action); > } > > public static abstract class PhantomCleanable extends PhantomReference > implements Cleanable { ... } > > private static final class PhantomCleanup extends PhantomCleanable implements > Cleanup { ... } > > ...use... > > class SuperClass { > protected final Cleanup cleanup = XXX.getCleaner().phantomCleanup(this); > > SuperClass() { > cleanup.append(() -> {... super class cleanup ...}); > } > } > > class SubClass extends SuperClass { > SubClass() { > super(); > cleanup.prepend(() -> {... pre-actions ...}) > .append(() -> {... post-actions ...}); > } > } > > > Regards, Peter > >> >> >> >> On 10/14/2015 10:23 AM, Alan Bateman wrote: >>> >>> On 14/10/2015 15:03, Roger Riggs wrote: >>>> Hi Alan, >>>> >>>> So any user of the Cleaner can take advantage of the mechanism, for >>>> example in a different package or module. >>>> For example, Netbeans. >>> Cleaner + Cleanable need to be public of course so maybe we should wait for >>> the examples that extend WeakCleanableRef or cast the Cleanable to a >>> WeakCleanableRef before seeing if this is the right thing or not. >>> >>> -Alan >> >