On 12/05/2015 05:28 PM, Mandy Chung wrote:
On Dec 5, 2015, at 3:12 AM, Peter Levart <peter.lev...@gmail.com> wrote:



On 12/04/2015 10:58 PM, Mandy Chung wrote:
"It is possible to create a phantom reference with a null queue, but such a 
reference is completely useless: Its get method will always return null and, since 
it does not have a queue, it will never be enqueued.”

The puzzling part to me is why PhantomReference accepts null ReferenceQueue.   
I can’t evaluate how high of the source incompatibility risk if we fixed it but 
I may propose that in a future release until I have cycle.

Mandy

Well, it is not completely useless for PhantomReference to accept null ReferenceQueue. It's 
sometimes useful to have a common subtype of PhantomReference where most of instances perform a 
function of PhantomReference, but some instances are just there to provide the "glue" in 
the data structure. See the implementation of java.lang.ref.Cleaner and it's "root" nodes 
of a doubly-linked list ;-)
That’s right.

There may likely be some reason why it takes the null ReferenceQueue as noted 
in this comment in sun.misc.Cleaner:
     // Dummy reference queue, needed because the PhantomReference constructor
     // insists that we pass a queue.

Mandy

Digging up the src.jar of JDK 1.2.2, here's what the constructor of PhantomReference looked like:

    /**
     * Creates a new phantom reference that refers to the given object and
     * is registered with the given queue.
     *
     * @throws  NullPointerException  If the <code>queue</code> argument
     *                                is <code>null</code>
     */
    public PhantomReference(Object referent, ReferenceQueue q) {
        super(referent, q);
    }


...so it seems Mark wanted PhantomReference constructor to throw NPE. But implementation did not do that (here's also the constructor of Reference):


    Reference(Object referent, ReferenceQueue queue) {
        this.referent = referent;
        if (referent == null) {
            /* Immediately make this instance inactive */
            this.queue = ReferenceQueue.NULL;
            this.next = this;
        } else {
            this.queue = (queue == null) ? ReferenceQueue.NULL : queue;
            this.next = null;
        }
    }


...and so the spec. has probably been modified to follow the standing behavior.



Regards, Peter

Reply via email to