2012-03-29 2 views
0

Я читал на Дженерики в последнее время, и я наткнулся на этот метод:Java - Дженерики Метод

protected <V> RunnableScheduledFuture<V> decorateTask(Callable<V> callable, RunnableScheduledFuture<V> task) { 
     return new ExceptionHandlingFutureTask<V>(callable, task); 
    } 

Вы видите, я понимаю, почему есть <V> после protected. Я не понимаю, почему есть <V> снова после RunnableScheduledFuture. Я взял этот конкретный <V> из метода, скомпилировал его и не было ошибки. Так почему же тогда автор решил поставить его там в первую очередь?

ответ

2

Вообще говоря, вы можете всегда удалить дженерики с «без ошибок», поскольку они реализуются в Java с помощью стиранию, поэтому фактический скомпилированный код просто в любом случае относится к исходным классам. (Тем не менее, вам нужно вставить некоторые роли, чтобы компилятор был счастлив).

В свете последнего случая, удалив общий параметр из будущего, вы превратили его из «будущего, которое будет возвращать V» в «будущее, которое будет возвращать что-то». Без общего параметра людям нужно будет придать результат типу, который им нужен, и компилятор не сможет проверить правильность этого для них.

Это то же самое, что и использование необработанного ArrayList вместо ArrayList<Integer>; оба из них «работают», но последний более чист, легче понимает, проверяет тип компилятором и не требует ручного литья.

+0

Aaaaaaah, я вижу! Большое спасибо. Сейчас имеет большой смысл :) –

1

Потому что вы указываете, что возвращаете RunnableScheduledFuture<V>, в котором V - это тот же тип Callable, который вы положили на ваш вход.

Если удалить <V>, вы не получите сообщение об ошибке, если вы вызываете метод таким образом

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

Но, если вы не удалите <V>, это даст вам ошибку компилятора.

0

Потому что он хочет, чтобы избежать предупреждения произнесения когда

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

RunnableScheduledFuture требует параметризованного типа. Даже если вы можете удалить параметризованный тип из своего кода (и, таким образом, стать сырым типом), определение класса параметризуется.

Извлечение параметризованного типа потребует от вас приведения типа к соответствующему типу позже.

Смежные вопросы