Incompatibilidade de tipo ao usar Map.entrySet ()

Eu tenho a seguinte situação: No código abaixo, o método foo compila enquanto a bar método não. Na chamada de método entrySet (indicada no código), o compilador diz:

 Type mismatch: cannot convert from Set<Map.Entry> to Set<Map.Entry> 

Curiosamente, a correcção rápida do Eclipse propõe

 Change type of 's' to Set<Entry> 

que altera apenas o código porque a correção rápida está ignorando sua própria proposta e alterando o tipo de s para Set .

Eu estou usando o JDK1.8.0_51 e o Eclipse 4.4.0. Talvez tenha algo a ver com os curingas ou capturas? Qualquer ajuda ou conselho seria bem-vindo. Desde já, obrigado!

 import java.util.Iterator; import java.util.Map; import java.util.Map.Entry; import java.util.Set; public class MyClass { public void foo(Set<Entry> set) { Iterator<Entry> i = set.iterator(); } public void bar(Map map) { Set<Entry> s = map.entrySet(); ^^^^^^^^^^^^^^ } } 

A resposta curta é que, se você declarasse o Set da maneira que você tem em sua pergunta, seria possível adicionar inputs a ele que não estivessem de acordo com os tipos de objects passados ​​para o método. Java não retém informações suficientes para verificar se o “? Estende K” na definição do Conjunto é o mesmo que o “? Estende o K” no parâmetro do método.

Para evitar isso, o Java exige que você declare a atribuição como:

 Set> s = map.entrySet(); 

… e você descobrirá que não pode adicionar suas próprias inputs a este conjunto – pelo menos, não sem fazer muito vazamento ruim, o que gerará muitos avisos.

Como alguém mencionado acima, esta questão aborda o assunto em mais detalhes: Iterador Genérico no Conjunto de Entrada

Imagine que K e V são números. A declaração não vincula os tipos passados ​​com o mapa àqueles usados ​​no conjunto de input. Embora saibamos que isso nunca poderia acontecer, se map for um Map , a declaração permite que s seja um Set> vez que ainda estende Number.

Portanto, se você estiver explícito que esses tipos correspondem, escrevendo isto:

 public  void bar(Map map) { Set> s = map.entrySet(); } 

Seu significado é explícito, de que o tipo de ‘s’ corresponderá exatamente aos tipos de ‘mapa’. Por isso, compila feliz.