/ / Java: Generic downing генерує попередження, чому? - java, дженерики, компілятор-попередження

Java: Загальне викидання створює попередження, чому? - java, генерики, компілятори-попередження

Я не розумію, чому наступний код генерує попередження.

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 типу як "Загальний".