Java编译错误:结合了重载的方法参考 [英] Java Compile Error: Method reference in combination with overloading
问题描述
我有以下带有重载方法的类:
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屋!