JDK 11.0.2 在匿名参数化类类型推断上使用 javac NPE 编译失败

代码(弹簧网 5.1.2)

public static void main(String[] args) {
    RestTemplate restTemplate = new RestTemplate();

    HttpHeaders headers = new HttpHeaders();
    headers.set(HttpHeaders.AUTHORIZATION, "token");
    HttpEntity<Object> requestEntity = new HttpEntity<>(headers);

    ResponseEntity<Object> test = restTemplate.exchange(
            "https://example.com",
            HttpMethod.GET,
            new HttpEntity<>(headers),
            new ParameterizedTypeReference<>() { // fails here
            });
}

OracleJDK 1.8 (预期输出)

无法推断 org.springframework.core.ParameterizedTypeReference 的类型参数

原因:不能对匿名内部类使用“<>”

OracleJDK 11.0.2 (未預期出獲出)

编译器消息文件 broken: key=compiler.misc.msg.bug arguments=11.0.2, {1}, {2}, {3}, {4}, {5}, {6}, {7} java.lang.NullPointerException at jdk.compiler/com.sun.tools.javac.comp.Flow$FlowAnalyzer.visitApply(Flow.java:1235) at jdk.compiler/com.sun.tools.javac.tree.JCTree$JCMethodInvocation.accept(JCTree.java:1634) at jdk.compiler/com.sun.tools.javac.tree.TreeScanner.scan(TreeScanner.java:49) at jdk.compiler/com.sun.tools.javac.comp.Flow$BaseAnalyzer.scan(Flow.java:398) at jdk.compiler/com.sun.tools.javac.comp.Flow$FlowAnalyzer.visitVarDef(Flow.java:989)
...

如果我将菱形运算符更改为显式类型

new ParameterizedTypeReference<>(){}new ParameterizedTypeReference<Object>(){}

然后代码在两个 JDK 上成功编译。

这是一个已知的编译器错误吗?


答案 1

Bug (JDK-8212586) 已提交并在版本 12 中修复

最小的、可验证的示例:

public static void main(String[] args) {
    new Bug<>(){};
}

static class Bug<T> {

    Bug() {
        test(new ParameterizedTypeReference<>(){});
    }

    void test(ParameterizedTypeReference<T> typeReference) {
    }
}

一些细节。


修复程序也已向后移植到 JDK 11 - https://bugs.openjdk.java.net/browse/JDK-8220578

在 JDK 11.0.4 版中可用。


答案 2

我遇到了同样的错误,你需要创建一个函数:

ParameterizedTypeReference<Object> createParameterizedTypeReference(){ return new ParameterizedTypeReference<>(){}; }

并称之为:

ResponseEntity<Object> test = restTemplate.exchange(
"https://example.com",
HttpMethod.GET,
new HttpEntity<>(headers),
createParameterizedTypeReference() { 
});

推荐