从 java8 迁移到 java9 时,对方法的引用不明确
reference to method is ambiguous when migrating from java8 to java9
我正在将一个项目从 JAVA 8 迁移到 JAVA 9,但我在使代码正常工作时遇到了一些问题。 JAVA 8 中的所有工作,但在 9 中我遇到以下错误:
Error java: reference to ok is ambiguous
both method <T>ok(java.util.function.Supplier<T>) and method ok(web.Procedure) match
调用方法时的代码如下:
public ResponseEntity<List<MailTemplateDto>> mailTemplateFindAll() {
return ok(() -> mailTemplateService.findAll());
}
这是实现:
public <T> ResponseEntity<T> ok(Supplier<T> action) {
return this.body(HttpStatus.OK, action);
}
public <T> ResponseEntity<T> ok(T body) {
return this.ok(() -> {
return body;
});
}
public ResponseEntity<Void> ok(Procedure action) {
action.invoke();
return this.status(HttpStatus.OK);
}
public ResponseEntity<Void> ok() {
return this.status(HttpStatus.OK);
}
过程接口代码:
@FunctionalInterface
public interface Procedure {
void invoke();
}
有什么想法吗?
可重现代码 ::
public class Q48227496 {
public A<?> test() {
return ok(() -> System.out.append("aaa"));
}
private class A<T> {
}
private <T> A<T> ok(java.util.function.Supplier<T> action) {
return new A<>();
}
public <T> A<T> ok(T body) {
return new A<>();
}
private <T> A<T> ok(Procedure action) {
return new A<>();
}
public <T> A<T> ok() {
return new A<>();
}
@FunctionalInterface
public interface Procedure {
void invoke();
}
}
导致 java9 编译器出现以下错误::
error: reference to ok is ambiguous
return ok(() -> System.out.append("aaa"));
^
both method <T#1>ok(Supplier<T#1>) in Q48227496 and method <T#2>ok(Procedure) in Q48227496 match
where T#1,T#2 are type-variables:
T#1 extends Object declared in method <T#1>ok(Supplier<T#1>)
T#2 extends Object declared in method <T#2>ok(Procedure)
这是一个错误。
已报告错误 ID:JDK-8195598
我进一步简化了你的例子:
public class Q48227496 {
public CompletableFuture<?> test() {
return ok(() -> System.out.append("aaa"));
}
public <T> CompletableFuture<T> ok(Supplier<T> action) {
return CompletableFuture.supplyAsync(action);
}
public <T> CompletableFuture<T> ok(T body) {
return CompletableFuture.completedFuture(body);
}
public CompletableFuture<Void> ok(Runnable action) {
return CompletableFuture.runAsync(action);
}
}
这在 Java 9 的发布版本中失败,带有“reference to ok is ambiguous
”,声明“both method <T>ok(Supplier<T>) in Q48227496 and method ok(Runnable) in Q48227496 match
”。
但只是改变了方法的顺序
public class Q48227496 {
public CompletableFuture<?> test() {
return ok(() -> System.out.append("aaa"));
}
public <T> CompletableFuture<T> ok(T body) {
return CompletableFuture.completedFuture(body);
}
public <T> CompletableFuture<T> ok(Supplier<T> action) {
return CompletableFuture.supplyAsync(action);
}
public CompletableFuture<Void> ok(Runnable action) {
return CompletableFuture.runAsync(action);
}
}
使编译器无任何错误地接受代码。
所以,很明显,这是一个编译器错误,因为方法声明的顺序永远不会影响代码的有效性。
此外,删除 ok(T)
方法使代码被接受。
请注意,无论何时编译器接受代码,它都会认为 ok(Supplier)
比 ok(Runnable)
更具体,这是匹配两者的函数参数的预期行为。
我正在将一个项目从 JAVA 8 迁移到 JAVA 9,但我在使代码正常工作时遇到了一些问题。 JAVA 8 中的所有工作,但在 9 中我遇到以下错误:
Error java: reference to ok is ambiguous
both method <T>ok(java.util.function.Supplier<T>) and method ok(web.Procedure) match
调用方法时的代码如下:
public ResponseEntity<List<MailTemplateDto>> mailTemplateFindAll() {
return ok(() -> mailTemplateService.findAll());
}
这是实现:
public <T> ResponseEntity<T> ok(Supplier<T> action) {
return this.body(HttpStatus.OK, action);
}
public <T> ResponseEntity<T> ok(T body) {
return this.ok(() -> {
return body;
});
}
public ResponseEntity<Void> ok(Procedure action) {
action.invoke();
return this.status(HttpStatus.OK);
}
public ResponseEntity<Void> ok() {
return this.status(HttpStatus.OK);
}
过程接口代码:
@FunctionalInterface
public interface Procedure {
void invoke();
}
有什么想法吗?
可重现代码 ::
public class Q48227496 {
public A<?> test() {
return ok(() -> System.out.append("aaa"));
}
private class A<T> {
}
private <T> A<T> ok(java.util.function.Supplier<T> action) {
return new A<>();
}
public <T> A<T> ok(T body) {
return new A<>();
}
private <T> A<T> ok(Procedure action) {
return new A<>();
}
public <T> A<T> ok() {
return new A<>();
}
@FunctionalInterface
public interface Procedure {
void invoke();
}
}
导致 java9 编译器出现以下错误::
error: reference to ok is ambiguous
return ok(() -> System.out.append("aaa"));
^
both method <T#1>ok(Supplier<T#1>) in Q48227496 and method <T#2>ok(Procedure) in Q48227496 match
where T#1,T#2 are type-variables:
T#1 extends Object declared in method <T#1>ok(Supplier<T#1>)
T#2 extends Object declared in method <T#2>ok(Procedure)
这是一个错误。
已报告错误 ID:JDK-8195598
我进一步简化了你的例子:
public class Q48227496 {
public CompletableFuture<?> test() {
return ok(() -> System.out.append("aaa"));
}
public <T> CompletableFuture<T> ok(Supplier<T> action) {
return CompletableFuture.supplyAsync(action);
}
public <T> CompletableFuture<T> ok(T body) {
return CompletableFuture.completedFuture(body);
}
public CompletableFuture<Void> ok(Runnable action) {
return CompletableFuture.runAsync(action);
}
}
这在 Java 9 的发布版本中失败,带有“reference to ok is ambiguous
”,声明“both method <T>ok(Supplier<T>) in Q48227496 and method ok(Runnable) in Q48227496 match
”。
但只是改变了方法的顺序
public class Q48227496 {
public CompletableFuture<?> test() {
return ok(() -> System.out.append("aaa"));
}
public <T> CompletableFuture<T> ok(T body) {
return CompletableFuture.completedFuture(body);
}
public <T> CompletableFuture<T> ok(Supplier<T> action) {
return CompletableFuture.supplyAsync(action);
}
public CompletableFuture<Void> ok(Runnable action) {
return CompletableFuture.runAsync(action);
}
}
使编译器无任何错误地接受代码。
所以,很明显,这是一个编译器错误,因为方法声明的顺序永远不会影响代码的有效性。
此外,删除 ok(T)
方法使代码被接受。
请注意,无论何时编译器接受代码,它都会认为 ok(Supplier)
比 ok(Runnable)
更具体,这是匹配两者的函数参数的预期行为。