Java编译错误:结合了重载的方法参考 [英] Java Compile Error: Method reference in combination with overloading

查看:138
本文介绍了Java编译错误:结合了重载的方法参考的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下带有重载方法的类:

I have the following class with an overloaded method:

import java.util.ArrayList;
import java.util.concurrent.Callable;

public abstract class Test {

  public void test1 () {
    doStuff (ArrayList::new); // compilation error
  }

  public void test2 () {
    doStuff ( () -> new ArrayList<> ());
  }

  public abstract void doStuff (Runnable runable);

  public abstract void doStuff (Callable<ArrayList<String>> callable);
}

方法test1导致编译错误并显示错误消息 The method doStuff(Runnable) is ambiguous for the type Test.

The method test1 results in a compilation error with the error message The method doStuff(Runnable) is ambiguous for the type Test.

我添加了第三个方法test3,它看起来像这样:

I've added a third method test3 which looks like this:

public void test3 () {
    doStuff ( () -> {
      new ArrayList<> ();
    });
  }

在这里执行方法doStuff(Runnable)很明显.

Here the method doStuff(Runnable) is executed which is obvious.

但是编译器如何确定在test2中执行两种方法中的哪一种?

But how does the compiler decide which of the two methods is executed in test2?

为什么我可以使用lambda表达式而不使用方法引用?

Why can I use the lambda expression but not the method reference?

test2中的lambda表达式使用返回可调用对象的方法,为什么方法参考尝试使用其他方法?

The lambda expression in test2 useses the method which returns the callable, why does the method reference try to use the other method?

在我看来,这就像一个Java错误.

This seems to me like a java bug.

修改: 它与ArrayList和/或它的通用类型无关.当您拥有Callable<String>或任何其他对象时,也会发生相同的错误.

It has nothing to do with the ArrayList and/or the generic type of it. Same error when you have Callable<String> or any other object.

预先感谢

Dimitri

推荐答案

好吧,我们可以简化一下:

Well, we can simplify this:

// takes a Runnable
public static void doStuff(Runnable runable) {
    System.out.println("Runnable");
}

// takes a Callable
public static void doStuff(Callable<List<String>> callable) {
    System.out.println("Callable");
}

还有两个额外的方法,它们是重载.

And two extra methods that are overloads.

private static List<String> go() {
    return null;
}

private static List<String> go(int i) {
    return null;
}

如果您这样称呼,您会怎么想?

What do you think will happen if you call this:

doStuff(YourClass::go);

是的...这将无法匹配.您可能会认为这很愚蠢,因为go是不带任何参数的,这很有意义,在这种简单情况下,对于您来说很容易做出判断,而对于编译器.从本质上讲,这就像一个僵局:

Yeah... this will fail to match. And you might think that this is stupid as it only makes sense that go is the one that takes no arguments, it is easy for you in this simple situation to make this judgment, it's not for the compiler. In essence this is like a dead-lock:

为了知道要调用哪个doStuff方法,我们需要知道要调用哪个go.同时要了解要调用哪个go,我们需要知道要调用哪个doStuff还是:

In order to know which doStuff method to call, we need to know which go to call; and at the same time to understand which go to call we need to know which doStuff to call, or:

我们需要解析方法以找到目标类型,但是我们需要知道目标类型以解析方法.

we need to resolve the method in order to find the target type, but we need to know the target type in order to resolve the method.

在您的情况下,ArrayList具有多个构造函数时也会发生同样的事情...

Same thing happens in your case with ArrayList having more than one constructors...

这篇关于Java编译错误:结合了重载的方法参考的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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