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
>> 
> 

Reply via email to