This discussion is archived
10 Replies Latest reply: Apr 29, 2010 2:53 AM by 843798 RSS

Problem with ReferenceQueue constructors for Soft/Weak/Phantom References

843798 Newbie
Currently Being Moderated
Not sure if this has come up before, but the Java SE 5 and on platform defines invalid constructors for PhantomReference, SoftReference, and WeakReference when the using a ReferenceQueue to enqueue referent objects. The issue is that ReferenceQueue.remove() returns the reference object, and not the referent, and thus the existing constructor which requires a ReferenceQueue<? super T> where T is the referent type is incorrect. The solution is to add a third constructor that takes as its queue parameter a reference queue with type signature of ReferenceQueue<? extends WeakReference<T>>, thereby providing the correct functionality and not breaking existing code. Further details and an example demonstrating the problem can be found on my blog.
  • 1. Re: Problem with ReferenceQueue constructors for Soft/Weak/Phantom References
    dcminter Newbie
    Currently Being Moderated
    Doesn't seem at all obvious to me that the existing implementation is incorrect - only that it contradicts your expectations. It does what the API docs say it should do.
  • 2. Re: Problem with ReferenceQueue constructors for Soft/Weak/Phantom References
    843798 Newbie
    Currently Being Moderated
    Why?

    ReferenceQueue returns a "Reference<? extends T>" from its methods and not a "T".

    Using a "ReferenceQueue<? extends WeakReference<T>>" would make poll() return a "Reference<? extends WeakReference<T>>", which is clearly wrong.
  • 3. Re: Problem with ReferenceQueue constructors for Soft/Weak/Phantom References
    800353 Newbie
    Currently Being Moderated
    You seem thoroughly confused! What a pity that you've already dedicated an entire blog entry to this non-existing "problem" ;-)
    A ReferenceQueue, as its name suggests, handles References, what else?

    Please have a look at the [non-generic JavaDoc|http://java.sun.com/j2se/1.4.2/docs/api/java/lang/ref/ReferenceQueue.html] to see that nothing has really changed with Java 5 (except the added type-safety)
  • 4. Re: Problem with ReferenceQueue constructors for Soft/Weak/Phantom Referenc
    843798 Newbie
    Currently Being Moderated
    Maybe I'm wrong, but I wouldn't jump to conclusions, and there is no need to get hostile.

    A couple of things are clear:

    1) The present definitions are fine if you do not subclass or wrap Weak/SoftReference<T>.
    2) It works because all methods in Weak/SoftReference are inherited from Reference<T>.
    3) Reference objects are put on ReferenceQueues, remove() should not erase their types.

    Now all that I want is consistent type checked behavior, and also backwards compatibility
    for older code that does not use generics. I admit that I wrote the blog entry fast and made
    a mistake -- since corrected.

    But, none the less the following fails:
    class MyWR<T> extends WeakReference<T> {
       MyWR(T r, ....);
    }
    When you ultimately pull the MyWR object off the queue you are forced to apply a cast.
    This should be possible without needing that cast -- That is all that I am saying. Here's
    my suggested solution, maybe not perfect, but it would work:

    Modify ReferenceQueue class as follows:
    class ReferenceQueue<T extends Reference<?>> {
        T remove();
        T poll();
    }
    After all the Reference queue contains only Reference objects as per the return type of
    remove() and poll().

    Redefine Soft/Weak reference constructors providing reference queues as follows:
    class WeakReference<T> extends Reference<T> {
        ...
        WeakReference(T referent, ReferenceQueue<? extends Reference<? extends T>> queue);
    }
    This is a breaking change for existing code, but allows for subclassing of Weak/Soft references
    as well as consistent operation of legacy (pre generics) code. Code using generics would have
    to provide an appropriate type signature.

    I was however wrong when I said it could be fixed by providing an additional constructor.
  • 5. Re: Problem with ReferenceQueue constructors for Soft/Weak/Phantom Referenc
    843798 Newbie
    Currently Being Moderated
    yup, I was wrong, see my post below. In my opinion its still broken, but the fix not so obvious.
  • 6. Re: Problem with ReferenceQueue constructors for Soft/Weak/Phantom Referenc
    dcminter Newbie
    Currently Being Moderated
    Maybe I'm wrong, but I wouldn't jump to conclusions.
    And yet you're still convinced that you're right about how this is supposed to work. Where does the actual behaviour of the API contradict the documented behaviour of the API?

    Again, test your expectations first - particularly before declaring that a much used API is "wrong".
  • 7. Re: Problem with ReferenceQueue constructors for Soft/Weak/Phantom Referenc
    843798 Newbie
    Currently Being Moderated
    bluehat1 wrote:
    This is a breaking change for existing code
    And as such isn't able to be implemented without a very good reason. And "but we can avoid casts for subclasses"! Is definitely not a good reason to break backwards compatibility in the core libraries.

    There's no use in discussion whether or not that would be a good chance, because it has no chance of ever being implemented.
  • 8. Re: Problem with ReferenceQueue constructors for Soft/Weak/Phantom Referenc
    843798 Newbie
    Currently Being Moderated
    Well, how's about I am convinced about how it "does" work, as opposed with how it should work.

    1. It does put references on the reference queue.
    2. The current API forces a cast where one should not be required.

    Perhaps, just perhaps, the original API was designed without regard for subclassing Weak/SoftReference etc.
    I mean, why would you want to do that right?

    Having said that, IF you subclass, the results are not-satisfactory with the current API. That's all. In my
    original post I failed to look at the return type of RefQueue.remove() because I wrongly expected the type
    to be a T, silly me.

    I did "TEST" my expectations, in fact, this whole thing is the result of running production code that is now
    somewhat convoluted due to the above issue.

    Anyway, I agree, its moot if a non-breaking change cannot be proposed, which appears to be the case.
  • 9. Re: Problem with ReferenceQueue constructors for Soft/Weak/Phantom Referenc
    EJP Guru
    Currently Being Moderated
    Perhaps, just perhaps, the original API was designed without regard for subclassing Weak/SoftReference etc.
    java.util.WeakHashMap does precisely that.
  • 10. Re: Problem with ReferenceQueue constructors for Soft/Weak/Phantom Referenc
    jschellSomeoneStoleMyAlias Expert
    Currently Being Moderated
    bluehat1 wrote:
    Well, how's about I am convinced about how it "does" work, as opposed with how it should work.
    There are three parts
    1. What the Java API javadocs say
    2. What the Java API does
    3. What you want.

    If there is a mismatch between 1 and 2 it is a bug. For this to be the case you must explicitly cite the javadocs and then provide code that behaves in a way that contradicts the javadocs in an obvious way.

    The last has nothing to do with the first two. And at best it is a RFE (Request for enhancement) which you can add to the java bug database if you wish. Nothing in my experience would suggest that normally the Java API will be changed once released. Additions (not modifications) at least have a chance of being added. With the Open source java you also have the option of modifying it yourself, of course then you code will only work on that.