Java 三元运算符对泛型类型推断的影响

2022-09-01 10:57:39
public List<String> foo1() {
    List<String> retval = bar();
    if (retval == null)
        return Collections.emptyList();
    else
        return retval;
}

public List<String> foo2() {
    List<String> retval = bar();
    return retval == null ? Collections.emptyList() : retval;
}

为什么编译正常而有错误?(更准确地说是“类型不匹配:无法从 List<capture#1-of 转换?将 Object> 扩展为 List<String>”foo1()foo2())

我本来以为两个函数都会编译成相同的字节码,所以一个聪明的编译器应该推断出正确的类型......emptyList()


答案 1

在java 8中为我编译得很好。

早期版本的 Java 可能需要更多帮助

return retval == null ? Collections.<String>emptyList() : retval;

应该工作。

编辑这是由于Java 8类型推断的改进,如此处所述

http://openjdk.java.net/jeps/101

这是一个博客,其中包含亮点:http://blog.jooq.org/2013/11/25/a-lesser-known-java-8-feature-generalized-target-type-inference/


答案 2

这与泛型方法中的类型推断有关。

如果是版本 8 之前的代码。必须声明此情况的结果类型。

return retval == null ? Collections.<String>emptyList() : retval;

自第 8 版以来,什么是目标类型的概念已扩展为包含方法参数。因此,不再需要这样做。


推荐