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