Akinwale Agbaje
Akinwale Agbaje

Reputation: 315

Java - Generics Method

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?

Upvotes: 0

Views: 139

Answers (4)

Buhake Sindi
Buhake Sindi

Reputation: 89189

Because RunnableScheduledFuture requires a parameterized type. Even though you can remove parameterized type from your code (and thus becoming a raw-type), the class definition is parameterized.

Removing the parameterized type, will require you to typecast to the appropriate type later.

Upvotes: 0

Andrzej Doyle
Andrzej Doyle

Reputation: 103837

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 ArrayList instead of ArrayList<Integer>; both of them "work", but the latter is cleaner, easier to understand, type-checked by the compiler and doesn't require manual casting.

Upvotes: 2

Luca
Luca

Reputation: 4273

Because he wants avoid cast warning when

ExceptionHandlingFutureTask<V> var = decorateTask(...);

Upvotes: 0

manub
manub

Reputation: 4100

Because you're specifying that you're returning a RunnableScheduledFuture<V>, in which V is the same type of the Callable you put in your input.

If you remove <V>, you will get no error if you call the method in this way

RunnableScheduledFuture<String> rsf = decorateTask(Callable<Integer> callable, RunnableScheduledFuture<Integer> task);

But, if you don't remove the <V>, this will give you a compiler error.

Upvotes: 1

Related Questions