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(); }