/ / Java: derrubar genérico gera aviso, por quê? - java, genéricos, avisos do compilador

Java: lançamento genérico gera aviso, por quê? - java, genéricos, compiladores-avisos

Não entendo por que o código a seguir gera um aviso.

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>

Na classe B, estou interessado apenas em usar instâncias de Genérico do tipo A. Esse aviso sugere que eu preciso armazenar o argumento Genérico como um T em vez de A.

Mas isso significa que eu teria que declarar B genérico também, o que parece tornar as coisas mais complicadas do que precisam.

Respostas:

6 para resposta № 1

Isso não diminui, pois os genéricos Java são invariantes: Generic<T> não é um subtipo de Generic<A> mesmo que T seja um subtipo de A. Se você precisar apenas de métodos genéricos que retornem A, poderá usar curinga Generic<? extends A> no construtor B e no campo que armazena a referência.


5 para resposta № 2

Porque um Generic<T> não é um subtipo de Generic<A> mesmo se T é um subtipo de A.

Para ilustrar isso, considere String instancia de Object:

List<String> listOfStrings = new ArrayList<String>();
List<Object> listOfObjects = (List<Object>)listOfStrings; // invalid
listOfObjects.add(new Date());
// now listOfStrings contain a date!

O compilador não permite essa conversão, porque pode causar danos à lista original. A JVM não impõe requisitos genéricos de limites no tempo de execução.

A solução aqui é declarar o campo c digite como "Genérico".