This is a well-known idiom in Java. See for instance this SO discussion. So basically to define an interface whereby classes that implement it need to have a method to compare with objects of their class you would do:
public interface IComparable<T extends IComparable<T>> {
public int compare(T item);
}
(Note: that's apparently an unnecessarily complicated way to solve the particular use case - see this post - but I am inquiring on how to interpret the recursive syntax, never mind the particular application).
In short, this is a recursive definition with no apparent end in the recursion and I don't see how the compiler / type system pull this off.
Also, trying to put in words ("an IComparable is a class whose instances can compare with objects of a class that implements the IComparable interface") yields an illogical circular definition that can't be had in Philosophy / Logic / Mathematics but apparently is doable in compiler design (!).
Further, it would seem that if the original idiom syntax is acceptable then one might also be allowed to say:
public interface IComparable<T extends IComparable<T extends IComparable<T>>> {
public int compare(T item);
}
... but the compiler balks at that apparently allowing only one level of extend
.
Can anyone shed some light to help me grok this kind of recursive generic definitions?
UPDATE
Based on the accepted answer (BartoszKP) what I think I now understand is the following:
The "recursive" definition should NOT be read as (arrows representing the "the definition depends on" relationship):
[ IComparable<T> ] -------> [ IComparable<T> ]
... which is illogical (circular), but rather as:
[ IComparable<T> ] ----------> [ list of methods (parameterized by T) ]
\ ^
\ |
\-------> [ type bound on T ]-------/
... which is not illogical and thus doable in the compiler. So, in words, the definition of IComparable
is given in terms of the list of methods it defines and the bound it defines on type T
and the latter in turn also depends on the list of methods. So, no recursion.