I’ve been reading on Generics lately, and I came across this method:
protected <V> RunnableScheduledFuture<V> decorateTask(Callable<V> callable, RunnableScheduledFuture<V> task) {
return new ExceptionHandlingFutureTask<V>(callable, task);
}
You see, I understand why there’s a <V> after protected. What I don’t understand is why there’s a <V> again after RunnableScheduledFuture. I took this particular <V> out of the method, compiled it and there was no error. So why then did the writer decide to put it in there in the first place?
Generally speaking, you can always remove generics with “no error”, because they’re implemented in Java via erasure, so the actual compiled code simply refers to the raw classes anyway. (That said, you’d need to insert some casts to keep the compiler happy).
In light of the latter case, by removing the generic parameter from the future, you’ve turned it from “a future that will return a
V” into “a future that will return something“. Without the generic parameter, people will need to cast the result into the type they want, and the compiler won’t be able to check the correctness of this for them.It’s just the same as being able to use a raw
ArrayListinstead ofArrayList<Integer>; both of them “work”, but the latter is cleaner, easier to understand, type-checked by the compiler and doesn’t require manual casting.