JDK 11.0.2 编译在匿名参数化 class 类型推断上使用 javac NPE 失败
JDK 11.0.2 compilation fails with javac NPE on anonymous parameterized class type inference
代码 (spring-web 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(预期输出)
cannot infer type arguments for
org.springframework.core.ParameterizedTypeReference
reason: cannot use '<>' with anonymous inner classes
OracleJDK 11.0.2(不是预期的输出)
compiler message file 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 上编译成功。
这是一个已知的编译器错误吗?
错误(JDK-8212586) has been already submitted and fixed 版本 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.
我有同样的错误,你需要创建一个函数:
ParameterizedTypeReference<Object> createParameterizedTypeReference(){ return new ParameterizedTypeReference<>(){}; }
并称它为:
ResponseEntity<Object> test = restTemplate.exchange(
"https://example.com",
HttpMethod.GET,
new HttpEntity<>(headers),
createParameterizedTypeReference() {
});
Java11.0.7也有同样的问题
这改变自:
new ParameterizedTypeReference<>() {
})
对此:
new ParameterizedTypeReference<HashMap<String, MyClass>>() {
})
正如之前的评论所指出的,问题在于参数化匿名 类,例如从 Guava 使用 TypeToken 时,这 NOT 工作:
public List<SomeClass> list() {
return getData(new TypeToken<>() { });
}
但这确实有效:
public List<SomeClass> list() {
return getData(new TypeToken<List<SomeClass>>() { });
}
我在 11.0.3 - 11.0.7 版本中尝试过,并且都包含错误。
我已经通过升级到 AdoptOpenJDK 11.0.8 解决了我机器上的这个问题。
代码 (spring-web 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(预期输出)
cannot infer type arguments for org.springframework.core.ParameterizedTypeReference
reason: cannot use '<>' with anonymous inner classes
OracleJDK 11.0.2(不是预期的输出)
compiler message file 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 上编译成功。
这是一个已知的编译器错误吗?
错误(JDK-8212586) has been already submitted and fixed 版本 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.
我有同样的错误,你需要创建一个函数:
ParameterizedTypeReference<Object> createParameterizedTypeReference(){ return new ParameterizedTypeReference<>(){}; }
并称它为:
ResponseEntity<Object> test = restTemplate.exchange(
"https://example.com",
HttpMethod.GET,
new HttpEntity<>(headers),
createParameterizedTypeReference() {
});
Java11.0.7也有同样的问题
这改变自:
new ParameterizedTypeReference<>() {
})
对此:
new ParameterizedTypeReference<HashMap<String, MyClass>>() {
})
正如之前的评论所指出的,问题在于参数化匿名 类,例如从 Guava 使用 TypeToken 时,这 NOT 工作:
public List<SomeClass> list() {
return getData(new TypeToken<>() { });
}
但这确实有效:
public List<SomeClass> list() {
return getData(new TypeToken<List<SomeClass>>() { });
}
我在 11.0.3 - 11.0.7 版本中尝试过,并且都包含错误。
我已经通过升级到 AdoptOpenJDK 11.0.8 解决了我机器上的这个问题。