Я не розумію, чому наступний код генерує попередження.
interface Generic<T> {
}
interface A {
}
class B {
Generic<A> c;
<T extends A> B(Generic<T> a) {
c = (Generic<A>) a; //warning here
}
}
//Unchecked cast from Generic<T> to Generic<A>
У класі B я зацікавлений лише у використанні екземплярів Generic, які мають тип A. Це попередження передбачає, що мені потрібно зберігати загальний аргумент як T замість A.
Але це означає, що я мав би також оголосити B генериком, який, здається, робить речі складнішими, ніж вони повинні бути.
Відповіді:
6 за відповідь № 1Це не є відкиданням, оскільки генератори Java інваріантні: Generic<T>
не підтип Росії Generic<A>
хоча T є підтипом A. Якщо вам потрібні тільки загальні методи, які повертають A, ви можете використовувати шаблон Generic<? extends A>
в B-конструкторі і в полі, в якому зберігається посилання.
5 для відповіді № 2
Тому що а Generic<T>
не є підтипом Generic<A>
навіть якщо T
є підтипом A
.
Щоб проілюструвати це, розглянемо String
примірник Object
:
List<String> listOfStrings = new ArrayList<String>();
List<Object> listOfObjects = (List<Object>)listOfStrings; // invalid
listOfObjects.add(new Date());
// now listOfStrings contain a date!
Компілятор не допускає цього виклику, оскільки він може призвести до пошкодження вихідного списку.
Рішення тут полягає в оголошенні поля c
типу як "Загальний".