为什么这段代码在java 11中能正常编译?

问题描述 投票:0回答:1

下面是代码。

import java.util.*;

public class Main {
    public static <T> T defaultIfNull(T object, T defaultValue) {
        return object != null ? object : defaultValue;
    }

    public static void main(String[] args) {
        List<String> ls = Collections.emptyList();
        List<String> lo = defaultIfNull(ls, Collections.emptyList());
    }
}

openjdk 11,它编译得很好。

root@debian:~/tmp# java -version
openjdk version "11.0.6" 2020-01-14
OpenJDK Runtime Environment (build 11.0.6+10-post-Debian-1deb10u1)
OpenJDK 64-Bit Server VM (build 11.0.6+10-post-Debian-1deb10u1, mixed mode, sharing)

root@debian:~/tmp# javac ./Main.java

但是,这并不是说 openjdk 1.8:

root@debian:~/tmp# /usr/local/java-se-8u41-ri/bin/java -version
openjdk version "1.8.0_41"
OpenJDK Runtime Environment (build 1.8.0_41-b04)
OpenJDK 64-Bit Server VM (build 25.40-b25, mixed mode)
root@debian:~/tmp# /usr/local/java-se-8u41-ri/bin/javac ./Main.java
./Main.java:12: error: incompatible types: inferred type does not conform to upper bound(s)
        List<String> lo = defaultIfNull(ls, Collections.emptyList());
                                       ^
    inferred: List<? extends Object>
    upper bound(s): List<String>,Object
1 error

这里的问题是: Collections.emptyList 返回 List<Object> 如果没有提供类型参数。那么,是什么让它可以 openjdk 11 来做同样的事情?

java generics type-inference
1个回答
3
投票

这是一个 javac工具的错误 (如上所述 此处),已经在以后的版本中得到了修复。你应该更新你的jdk到一个新的版本来解决这个问题(同时也应用安全补丁)。

另外,如果不能更新你的jdk版本,你也许可以通过指定类型来帮助编译器,比如这样。

List<String> lo = Main.<List<String>>defaultIfNull(ls, Collections.<String>emptyList());

我还没有测试过这个,因为我没有使用你的版本,但在这种情况下可能会有用。

© www.soinside.com 2019 - 2024. All rights reserved.