我今天用我认为应该有效的代码破坏了构建:
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
public class EmptyListTest {
public static void main(String[] args) {
HashMap<Integer,List<String>> map = new HashMap<Integer,List<String>>();
map.put(Integer.valueOf(0), Collections.emptyList());
}
}
Eclipse Java编译器对这段代码没有问题,但是Oracle的javac
失败并显示此消息:
src/java/EmptyListTest.java:9: error: no suitable method found for put(Integer,List<Object>)
map.put(Integer.valueOf(0), Collections.emptyList());
^
method Map.put(Integer,List<String>) is not applicable
(argument mismatch; List<Object> cannot be converted to List<String>)
method AbstractMap.put(Integer,List<String>) is not applicable
(argument mismatch; List<Object> cannot be converted to List<String>)
method HashMap.put(Integer,List<String>) is not applicable
(argument mismatch; List<Object> cannot be converted to List<String>)
1 error
4 warnings
显而易见的事情是通过向 Collections.emptyList()
添加强制转换来帮助 Oracle 编译器。 ,但这当然会导致其自身的编译器错误(对于 Eclipse 和 javac
):
/Users/chris/Documents/Eclipse/chadis-web/src/java/EmptyListTest.java:9: error: incompatible types: List<Object> cannot be converted to List<String>
map.put(Integer.valueOf(0), (List<String>)Collections.emptyList());
我很清楚 Java 对泛型的支持官方很糟糕,但这似乎是一个应该可行的常见情况。我知道我可以使用正确的数据类型手动实例化一个空列表,但这很浪费。我知道我可以将这行代码分成两部分(一个声明 List<String>
并赋值给 Collections.emptyList()
,另一行调用 Map<Integer,List<String>>.put()
,但这只是更多代码没有充分的理由。
我还能做些什么来说服 Oracle javac
该代码有效吗?
更新:使用 Eclipse Luna(不确定编译器版本)和 Oracle Java 1.8.0_151。
更新 2:看起来这是由 -source 1.5
的存在引起的作为编译器的参数之一。使用默认的source
对于 javac
不会导致任何错误。奇怪的是Collections.emptyList()
当它自 Java 1.5 以来没有更改时,跨版本的行为会有所不同。跨版本的删除处理肯定发生了某种变化,使得它在不同的源兼容性级别上的工作方式有所不同。
最佳答案
在某些 Java 版本(Java 8 之前的版本,包括源兼容性设置小于 1.8
的 Java 8)中,您需要指定泛型类型,以便 emptyList
将返回一个通用列表而不是原始列表。您可以使用以下方法来做到这一点:
Collections.<String>emptyList()
在最新的 Java 版本中,编译器可以从上下文中推断出所需的泛型类型,因此您无需指定它。此扣除额为added in Java 8这样您在使用流时不必在链中的每个步骤都指定泛型类型。
关于java - 为什么 Java 不解析这个 <generic> 方法签名?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47782956/