Java generics bounds with recursive type parameters

Viewed 1708

I have a base class Thing, which provides some base functionality, including getting a reference to a ThingInfo with the type parameter of the type of the Thing sub class. Because Java does not have self types, I cannot use that for the type parameter to the ThingInfo return value, so Thing must take a recursive type parameter to allow us to return the correct parameterized ThingInfo.

interface ThingInfo<T>
{
    // just an example method showing that ThingInfo needs to know about
    // the type parameter T
    T getThing();
}

class Thing<T extends Thing<T>>
{
    // I need to be able to return a ThingInfo with the type parameter
    // of the sub class of Thing. ie. ThingA.getThingInfo() must return
    // a ThingInfo<ThingA>.
    // This is where Java would benefit from self types, as I could declare
    // the method something like: ThingInfo<THIS_TYPE> getThingInfo()
    // and Thing would not need a type parameter.
    ThingInfo<T> getThingInfo()
    {
        return something;
    }
}

// example Thing implementation
class ThingA extends Thing<ThingA>
{
}

// example Thing implementation
class ThingB extends Thing<ThingB>
{
}

So far everything is fine. This code works as needed.

I also need to represent a type safe relationship between Things.

class ThingRelation<X extends Thing<X>, Y extends Thing<Y>>
{
    X getParent()
    {
        return something;
    }

    Y getChild()
    {
        return something;
    }
}

Its not really that simple, but that demonstrates the need I think. Still, all of this is fine, no error yet. Now, ThingRelation needs method that takes an argument of a ThingRelation between Y and some other Thing. So I change ThingRelation to the following:

class ThingRelation<X extends Thing<X>, Y extends Thing<Y>>
{
    X getParent()
    {
        return something;
    }

    Y getChild()
    {
        return something;
    }

    <Z extends Thing<Z>> void useRelation(ThingRelation<Y, Z> relation)
    {
        // do something;
    }
}

But now I get this error when compiling it:

type argument Y is not within bounds of type-variable X
  where Y,X are type-variables:
    Y extends Thing<Y> declared in class ThingRelation
    X extends Thing<X> declared in class ThingRelation

The error is on the line starting <Z extends Thing<Z>>....

What on earth could be the problem?

Update: The javac version is 1.7.0_05.

1 Answers
Related