从java8迁移到java9时,对方法的引用是不明确的 [英] reference to method is ambiguous when migrating from java8 to java9

查看:1319
本文介绍了从java8迁移到java9时,对方法的引用是不明确的的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在将项目从JAVA 8迁移到JAVA 9,我在使代码工作时遇到了一些麻烦。所有工作都在JAVA 8但在9中我遇到以下错误:

I'm migrating a project from JAVA 8 to JAVA 9 and I'm having some trouble getting the code to work. All work in JAVA 8 but in 9 I'm having the following errors:

Error java: reference to ok is ambiguous
      both method <T>ok(java.util.function.Supplier<T>)  and method ok(web.Procedure) match

这是我调用方法时的代码:

here is the code when I'm calling the method:

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();
}

任何想法?

可重复代码 ::

Reproducible Code ::

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 compiler ::

Resulting in the following error with java9 compiler::

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

This is a bug.

It has been reported with bug ID : JDK-8195598

我进一步简化了你的例子:

I simplified your example further:

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的发布版本中失败了 对ok的引用不明确,在Q48227496中声明两种方法< T> ok(供应商< T>)和方法ok(Runnable)in Q48227496匹配

This fails in the release version of Java 9 with "reference to ok is ambiguous", stating "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);
    }
}

使编译器接受代码而没有任何错误。

causes the compiler to accept the code without any errors.

所以,显然,这是一个编译器错误,因为方法声明的顺序不应该对代码的有效性产生影响。

So, obviously, this is a compiler bug as the order of the method declarations should never have an impact on the validity of the code.

此外,删除 ok(T)方法会使代码被接受。

Also, removing the ok(T) method makes the code accepted.

请注意,只要编译器接受代码,它就会认为 ok(Supplier)更具体(ok)(Runnable) ,这是与两者匹配的函数参数的预期行为。

Note that whenever the compiler accepts the code, it considers ok(Supplier) to be more specific than ok(Runnable), which is the expected behavior for a function parameter that matches both.

这篇关于从java8迁移到java9时,对方法的引用是不明确的的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆