Consider this simplified task.
interface Item<C extends Container<Item<C>>> interface Container<I extends Item<Container<I>>>
This does not work because the subtypes of Container<Item<C>> quite limited - Container<MyItem> not a subtype of this, just as List<string> not a subtype of List<Object>
We can relax it with wildcards:
interface Item<C extends Container<? extends Item<C>>> interface Container<I extends Item<? extends Container<I>>>
Now it works great
class MyItem implements Item<MyContainer> class MyContainer implements Container<MyItem>
primarily. The following announcement is also allowed, but not what we intended
class HerItem implements Item<MyContainer> // nooo!
This is because we have relaxed the restrictions too much. Well, this is not a very serious problem. Of course, our type system is not as dense as we want (there is no type system), but programmers will instinctively follow the intended restrictions, do not go out of their way to write fancy things just because they can.
Ideally, we need a type of This , and our alleged limitations can be expressed as
interface Item<C extends Container<This>>> interface Container<I extends Item<This>>
Since we donโt have This , we can try to get closer to it using a parameter
interface Item<C extends Container<This, C>>, This extends Item<C, This> > interface Container<I extends Item<This, I>, This extends Container<I, This>>
(or, more symmetrically
interface Item<C extends Container<I, C>>, I extends Item<C, I> > interface Container<I extends Item<C, I>, C extends Container<I, C>>
) However, this is also not very difficult. This is not really "this type." maybe
class HerItem implements Item<MyContainer, MyItem> // uh?
Again, we must rely on the discipline of the programmer to not do this.