reprodução mínima:
public class Main {
public static class TestGeneric<T> {
Map<String, Integer> testMap = new HashMap<>();
}
public static class Test {
Map<String, Integer> testMap = new HashMap<>();
}
public static class Irrelevant {}
public static void main(String[] args) {
// Not generic, no problem.
Test t = new Test();
Map.Entry<String, Integer> entry = t.testMap.entrySet().iterator().next();
// Generic, but variable type also include generic information.
TestGeneric<Irrelevant> t2 = new TestGeneric<>();
Map.Entry<String, Integer> entry2 = t2.testMap.entrySet().iterator().next();
// Generic, but variable type doesnt keep this info.
TestGeneric t3 = new TestGeneric<Irrelevant>();
Map.Entry<String, Integer> entry3 = t3.testMap.entrySet().iterator().next();
}
}
A última linha não compila porque Object cannot be converted to Entry<String, Integer>
.
A única diferença parece ser o tipo da variável "root". t3
é do tipo TestGeneric
enquanto t2
é TestGeneric<Irrelevant>
. Eu não entendo como o tipo da variável pode alterar o tipo de retorno de um atributo de classe cujo tipo não muda. Em todos os casos, testMap
continua a ser um Map<String, Integer>
, mas suas entrySet()
mudanças tipo de retorno.
Eu provavelmente sou mal-entendido alguma coisa com relação a Java genérico, mas o quê?
Obrigado,
Essa última linha não compilar, mas não porque você usar a Irrelevant
classe, mas porque a variável t3
é cru.
Quando se utiliza um tipo bruto, todas genéricos da classe, até mesmo genéricos não relacionados, tais como o parâmetro de tipo da testMap
variável, submetido a eliminação de tipo, como se fossem também cru. Isto é devido a regras de compatibilidade para trás a partir de quando os genéricos foram introduzidos para Java no JDK 1.5.
Efetivamente, isto significa que testMap
agora é apenas uma matéria Map
, cujos Iterator
retornos Object
. Isso faz com que o erro de compilação que você já viu. Você pode fornecer o parâmetro de tipo para a t3
variável e o erro de compilação serão removidos.
TestGeneric<Irrelevant> t3 = new TestGeneric<>();