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

时间:2021-10-23 22:28:26
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;
}

Why does foo1() compiles fine whereas foo2() has an error? (to be more precise "Type mismatch: cannot convert from List<capture#1-of ? extends Object> to List<String>")

为什么foo1()编译得很好而foo2()有错误? (更准确地说“类型不匹配:无法从List 转换为List ”) #1-of?extends>

I would have thought that both functions would compile to the same bytecode, so a clever compiler should infer the correct type for emptyList()...

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

2 个解决方案

#1


27  

Compiles for me fine in java 8.

在java 8中编译我很好。

Earlier versions of Java might need more help

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

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

should work.

EDIT This is due to improvements in Java 8 type inference as explained here

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

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

And here's a blog with the highlights: http://blog.jooq.org/2013/11/25/a-lesser-known-java-8-feature-generalized-target-type-inference/

这里有一个重点突出的博客:http://blog.jooq.org/2013/11/25/a-lesser-known-java-8-feature-generalized-target-type-in​​ference/

#2


6  

This is related with Type Inference from a generic method.

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

In case of code before ver. 8. It must be declared the type of result for this case.

如果是ver之前的代码。 8.必须声明此案例的结果类型。

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

return retval == null?集合。 emptyList():retval;

Since ver. 8 notion of what is a target type has been expanded to include method arguments. So this is no longer required.

自从ver。 8什么是目标类型的概念已经扩展到包括方法参数。所以这不再需要了。

#1


27  

Compiles for me fine in java 8.

在java 8中编译我很好。

Earlier versions of Java might need more help

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

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

should work.

EDIT This is due to improvements in Java 8 type inference as explained here

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

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

And here's a blog with the highlights: http://blog.jooq.org/2013/11/25/a-lesser-known-java-8-feature-generalized-target-type-inference/

这里有一个重点突出的博客:http://blog.jooq.org/2013/11/25/a-lesser-known-java-8-feature-generalized-target-type-in​​ference/

#2


6  

This is related with Type Inference from a generic method.

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

In case of code before ver. 8. It must be declared the type of result for this case.

如果是ver之前的代码。 8.必须声明此案例的结果类型。

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

return retval == null?集合。 emptyList():retval;

Since ver. 8 notion of what is a target type has been expanded to include method arguments. So this is no longer required.

自从ver。 8什么是目标类型的概念已经扩展到包括方法参数。所以这不再需要了。