java - 为什么 Java 不解析这个 <generic> 方法签名?

标签 java generics compiler-errors

我今天用我认为应该有效的代码破坏了构建:

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/

相关文章:

swift - 为什么要限制带有 Self 或 associatedtype 的协议(protocol)?

windows - GAE 转到 Windows - "Cannot run program", "is not a valid Win32 application"

Java泛型——获取类型

c++ - 如何在 MSVC++ 中启用警告 C6244?

scala - SBT 0.13.7 和 Scala 2.11.5 版本兼容性问题

java - Eclipse RCP 命令框架 : I am lost

java - 从jsp获取禁用的真实数据到struts2 Action 类

java - 使用 java/scala API 进行 Neo4j lucene 搜索

java - 如何在java中制作没有长度的数组?

c# - 错误消息 : "Cannot convert type ' string ?' to ' string' "