我今天用我认为应该有效的代码打破了构建:
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 和 { {1}}):
javac
我很清楚Java对泛型的支持是官方可怕的,但这似乎是应该起作用的常见情况。我知道我可以用正确的数据类型手动实例化一个空列表,但这很浪费。我知道我可以将这行代码分成两行(一行声明为 /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());
,作业分配给List<String>
,另一行则调用Collections.emptyList()
,但是只是更多代码没有充分理由。
我可以采取其他措施来说服甲骨文Map<Integer,List<String>>.put()
此代码有效吗?
更新:使用Eclipse Luna(不确定编译器版本)和Oracle Java 1.8.0_151。
更新2:看起来这是由于javac
作为编译器的参数之一而引起的。使用-source 1.5
的默认source
不会导致任何错误。奇怪的是javac
在版本自Java 1.5以来没有发生变化时表现不同。对于跨版本的擦除处理必定会有某种变化,这使得在不同的源兼容级别上工作方式有所不同。
答案 0 :(得分:3)
在某些Java版本(Java 8之前,包括源兼容性设置小于1.8
的Java 8)中,您需要指定泛型类型,以便emptyList
返回通用列表而不是原始的。你可以使用:
Collections.<String>emptyList()
在更新的Java版本中,编译器可以从上下文中推导出所需的泛型类型,因此您无需指定它。此推论为added in Java 8,因此您在使用流时不必在链中的每个步骤都指定泛型类型。