The Comparable interface has a generic type parameter, which is used for self-referencing in subclasses (I don’t know any other use for it) :
public interface Comparable<E> {
public int compareTo(E other);
}
public class ComparableInteger implements Comparable<ComparableInteger> {
private int val;
public void compareTo(ComparableInteger other) {
return val > other ? 1 : (val == other ? 0 : -1);
}
But what if you need to access methods of the interface on the generic type parameter? Then you can do a recursive declaration of the type parameter. Here is an example, where we have a task object, which can be subclassed in order to do some stuff. Lets say it has a clone method, that should return a copy of itself. Furthermore there is a method on the framework that executes the tasks, which clones the task, let’s say n times and executes them (please note: this example makes no sense, but intentionally):
public interface Task<T extends Task<T>> {
public T clone();
public void doWork();
}
public class TaskFramework<T extends Task<T>> {
public void executeTask(final T task, final int times) {
for(int i = 0; i < (times); i++) {
new Thread() {
public void run() {
task.clone().doWork();
}
}
}
}
public class ExampleTask extends Task<ExampleTask> {
private int val;
public ExampleTask(int val) {
this.val = val;
}
public ExampleTask clone() {
return new ExampleTask(this.val);
}
public doWork() {
System.out.println("Value: " + val);
}
public static void main(String[] args) {
TaskFramework<ExampleTask> framework = new TaskFramework<ExampleTask>();
ExampleTask task = new ExampleTask(5);
framework.executeTask(task, 2);
}
}
You might like to have a type parameter for the value, too. This would enable you to use the interface Callable for your task and return a value:
public interface Task<T extends Task<T, V>, V> extends Callable<V> {
public T clone();
public V call();
}