@pirho Вы правы

оложим, у меня есть метод

@SuppressWarnings("unchecked")
public <T extends Number> T getNumber() {
   try {
      return (T)number; 
   } catch (ClassCastException e) {
      return null;
   }
}

Если предположить,number является примеромIntegerвызывая метод вроде

Float f = getNumber();

результаты вClassCastException.

Я знаю (как-то), что это из-застирание типа но может ли кто-нибудь дать более глубокое объяснение, почему исключение возрастает до уровня назначения и не может быть перехвачено внутри метода?

НОТА: У меня есть версияpublic <T extends Number> T getNumber(Class<T> classT) который проверяет тип из classT, но надеялся избавиться от передачиclassT и перестал интересоваться вышеуказанной проблемой.

Ответы на вопрос(1)

Решение Вопроса

return (T)number становитсяreturn (Number)number (посколькуNumber это граница типаT), который не выдает исключение (так какnumber является примеромInteger).

С другой стороны, назначение

Float f = getNumber();

составлен в

Float f = (Float) getNumber();

посколькуgetNumber() возвращаетNumber, который не может быть назначенFloat переменная без приведения.

Этот бросок бросаетClassCastException когдаgetNumber() это неFloat.

4,6. Тип Erasure

Стирание типа - это отображение типов (возможно, включая параметризованные типы и переменные типов) на типы (которые никогда не являются параметризованными типами или переменными типов). Мы пишем | T | для стирания типа Т. Отображение стирания определяется следующим образом ...

Стирание переменной типа (§4.4) - это стирание ее крайней левой границы.

 pirho29 нояб. 2017 г., 10:02
Спасибо за ясный, понятный ответ (как вы можете писать так быстро и ясно, я завидую ...). Я полагаю, что если я уронил «Расширяем число»,<T> только это будетreturn (Object)number?
 Eran29 нояб. 2017 г., 10:04
@pirho Вы правы

Ваш ответ на вопрос