Java 7下如何用Guava一行创建同步Multimap?类型不匹配解惑
这个问题其实是Java 7泛型类型推断的局限性导致的,我来给你拆解一下原因和可行的解决办法:
为什么分开写可行?
当你把HashMultimap.create()赋值给Multimap<String, String> m时,编译器会根据变量m的声明类型,自动推断create()方法应该返回Multimap<String, String>类型的实例。这时候再把明确泛型的m传给Multimaps.synchronizedMultimap(),自然能完美匹配泛型要求。
为什么链式调用不行?
Java 7的泛型推断无法从方法调用的目标变量类型反向推导方法参数的泛型。也就是说,当你直接写Multimaps.synchronizedMultimap(HashMultimap.create())时,编译器没法从左边的Multimap<String, String> n推断出HashMultimap.create()应该返回Multimap<String, String>,所以create()会默认返回最宽泛的Multimap<Object, Object>,这就导致了「无法将Multimap<Object,Object>转换为Multimap<String,String>」的类型不匹配错误。
解决办法
方法一:显式指定泛型参数
直接给HashMultimap.create()加上明确的泛型声明,告诉编译器要创建的实例类型:
Multimap<String, String> n = Multimaps.synchronizedMultimap(HashMultimap.<String, String>create());
这里的<String, String>会强制create()返回Multimap<String, String>类型的实例,和目标变量的泛型完全匹配。
方法二:保留拆分写法
就是你已经尝试过的分步赋值方式:
Multimap<String, String> m = HashMultimap.create(); Multimap<String, String> n = Multimaps.synchronizedMultimap(m);
这种写法更直观,也能借助变量的声明类型帮编译器完成泛型推断,避免类型不匹配问题。
内容的提问来源于stack exchange,提问作者David Michael Gang

