Estou intrigado com este erro de compilação. Considere o trecho de código abaixo, ConcreteClass1
tem o seguinte erro de compilação:
Erro: (16, 28) Java: os tipos incompatíveis: java.util.Map java.lang.String, java.lang.String> não pode ser convertido para java.util.Map java.lang.String, Java.lang.Object>
No entanto, ConcreteClass2
compila com sucesso, simplesmente porque ele se estende AbstractClass
ao invés de AbstractClass<Object>
. Por que é isso?
abstract class AbstractClass<T extends Object> {
void testGenerics(Map<String, Object> map) {
}
}
class ConcreteClass1 extends AbstractClass<Object> {
public void testGenerics() {
Map<String, String> map = new HashMap<>();
super.testGenerics(map);
}
}
class ConcreteClass2 extends AbstractClass {
public void testGenerics() {
Map<String, String> map = new HashMap<>();
super.testGenerics(map);
}
}
ConcreteClass2
é declarado como um tipo cru, devido à inforamtion genérico omitido. Conforme oficial Raw Tipos tutorial :
tipos de matérias-aparecem em código legado porque muitas classes de API (como as classes Coleções) não foram genéricas antes JDK 5.0. Ao usar tipos matérias, você essencialmente obter um comportamento pré-genéricos
Devido à acima testGenerics(Map<String, Object> map)
é interpretado como testGenerics(Map map)
e pode ser executado com qualquer Map
objecto. Tudo devido a compatibilidade com pré código Java 5.
Você pode dar uma olhada em JLS 4,8 Tipos-primas .