Поскольку возвращаемое значение получается из любого аргумента, переданного методу во время выполнения, Java не может определить тип возвращаемого значения, и приведение всегда обязательно.
С другой стороны, если бы тип возвращаемого значения был известен при компиляции, то вы могли бы использовать более разумный подход. (Например, когда Компонент был бы универсальным типом, определяющим тип C
вместо передаваемого ему параметра):
Component myConverter = new Component<BigDecimal>() {
@Override
public IConverter<BigDecimal> getConverter() {
return new MonetaryBigDecimalConverter();
}
};
class Component<C> { // <-- Type of C is known at compile time!
public IConverter<C> getConverter() {
return null;
}
}
Поскольку компилятор теперь точно знает, что метод getConverter
вернет IConverter<BigDecimal>
, приведение не требуется.
Ваше собственное решение извлечения в переменную работает так же, как приведение к необработанному типу IConverter
, что также возможно. Не нужно его извлекать.
@Override
public <C> IConverter<C> getConverter(Class<C> type) {
return (IConverter) new MonetaryBigDecimalConverter();
}
При приведении к необработанному типу вместо того, чтобы сказать «я возвращаю конвертер типа BigDecimal» (что может быть неправильно, если переданный аргумент другого типа), вы теперь говорите «я возвращаю IConverter любого типа» (который стало возможным по причинам обратной совместимости, когда дженерики были введены в Java 1.5, но, конечно, могут выдавать RuntimeException
)