circular generics : interface IFoo <T extends IFoo <T>>

Actually - you don't need the recursive definition in your case.

public interface IComparable<T> {
  public int compare(T item);
}

public class Foo implements IComparable<Foo> {
  @Override
  public int compare(Foo o) {
    return 0;
  }
}

Is quite sufficient to define what you are attempting.

A common place for recursive definitions is when you are working with enum. You will often see E extends Enum<E> and in this context it actually makes a lot of sense because the Enum class is defined with a generic type E that it enumerates.

As a narrative to @NPE's post on the referenced discussion:

public interface ResultItem<T extends ResultItem<T>> {
    public int getConfidence();
    public boolean equals(T item);
    public T cloneWithConfidence(int newConfidence);
}

What is happening here is that instead of defining your class in terms of a specific generic class T you are stating that T must extend ResultItem, i.e. it is any subclass of ResultItem. Of course, since ResultItem is a generic class you have to give it's generic parameter which, in this case is T itself. Thus the T extends ResultItem<T>. This is not a recursive definition, it is a subclass capture definition.


This is a well-known idiom in Java.

No. It is not useful, and should not be used. With the exception of Enum (which is a special case because enum types are compiler-generated), this pattern is never seen anywhere in the official Java libraries, or anywhere in any official Java documentation.

The purpose of Generic bounds on a type variable is to set up a relationship so that code inside the generic class or generic method can use that guarantee to perform some operations without casts, which are potentially unsafe. Generics bounds should be as unrestrictive as possible while still preventing the casts in the code.

Therefore, the only legitimate purpose of a bound interface IComparable<T extends IComparable<T>> would be if 1) it's actually a class, not an interface (interfaces do not have code, and thus there are no casts to avoid), and 2) code in the class needs to perform the following operation: use a method to get T out of itself, and then call on that a method that requires IComparable<T>. Then, a guarantee that T extends IComparable<T> would allow this to be done without casts.

I've seen many uses of this pattern, and in 99% of the cases, they do not need to do the above-mentioned operation. Rather, 99% of the time, what people want to do is somehow express that T "is equal to" IComparable<T>, which the above pattern does not guarantee (and which is impossible to express in Java). It only guarantees that T extends IComparable<T>, but not that IComparable<T> extends T.

Most of the time when people use this pattern, they use it for a class inside of which they do (T)this. The fact that there needs to be a cast shows that this is potentially unsafe; that its type safety is not guaranteed by the bounds (there is no guarantee that this (of type IComparable<T>) extends T). It is actually unsafe; a well-known example is class Foo extends IComparable<Foo>, and then class Bar extends IComparable<Foo>, thus this (of type Bar) does not extends T (Foo).

So if you ever see that code, it is almost certainly written with some misconception about what it does, and it should almost always be changed to this:

public interface IComparable<T> {
    public int compare(T item);
}

As an exercise, I challenge you to find a snippet where interface IComparable<T extends IComparable<T>> works, and where interface IComparable<T> does not work.

Tags:

Java

Generics