Type inference with mutually recursive generic types

N

Niklas Matthies

It is possible to define mutually recursive generic types like:

interface Parent<P extends Parent<P, C>, C extends Child<P, C>>
{
Set<C> children();
}

interface Child<P extends Parent<P, C>, C extends Child<P, C>>
{
P parent();
}

Now one can write (for example):

class HumanParent implements Parent<HumanParent, HumanChild>
{
public Set<HumanChild> children() { ... }
}

class HumanChild implements Child<HumanParent, HumanChild>
{
public HumanParent parent() { ... }
}

But now I need to write a method (in some other class) like:

static <P extends Parent<P, C>, C extends Child<P, C>>
C someChildOf(P parent)
{
return parent.children().iterator().next();
}

I can use it with concrete types:

HumanParent humanParent = ...;
HumanChild humanChild = someChildOf(humanParent);

But when I try to use it with the generic wildcard type

Parent<?, ?> parent = ...;
Child<?, ?> child = someChildOf(parent); // doesn't compile

then javac complains:

<P,C>someChildOf(P) [...] cannot be applied to
(Parent<capture of ?,capture of ?>)

Is there any way to get type parameters to bind for recursive types
like Parent<?, ?> and Child<?, ?>?

Incidentally you already get the same error with just one type
parameter:

static <E extends Enum<E>> E f(E e) { ... }

Enum<?> e = null;
f(e); // doesn't compile:

<E>f(E) [...] cannot be applied to (java.lang.Enum<capture of ?>)

Of course in this case one can define f() as

static <E extends Enum<?>> E f(E e) { ... }

which compiles fine, but that's not an option with Parent/Child
because it breaks the Parent<->Child type mapping:

static <P extends Parent<?, ?>, C extends Child<?, ?>>
C someChildOf(P parent)
{
return parent.children().iterator().next(); // doesn't compile
}

incompatible types
found : Child<P,C>
required: C

Variations like

static <P extends Parent<?, C>, C extends Child<P, ?>>
C someChildOf(P parent) // doesn't compile
{
return parent.children().iterator().next();
}

type parameter C is not within its bound
type parameter P is not within its bound

obviously don't work either.

Any suggestions?

-- Niklas Matthies
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,906
Latest member
SkinfixSkintag

Latest Threads

Top