为什么这个 Java 方法调用被认为是模棱两可的?
我遇到了一个奇怪的错误消息,我认为它可能不正确。请考虑以下代码:
public class Overloaded {
public interface Supplier {
int get();
}
public interface Processor {
String process(String s);
}
public static void load(Supplier s) {}
public static void load(Processor p) {}
public static int genuinelyAmbiguous() { return 4; }
public static String genuinelyAmbiguous(String s) { return "string"; }
public static int notAmbiguous() { return 4; }
public static String notAmbiguous(int x, int y) { return "string"; }
public static int strangelyAmbiguous() { return 4; }
public static String strangelyAmbiguous(int x) { return "string"; }
}
如果我有一个看起来像这样的方法:
// Exhibit A
public static void exhibitA() {
// Genuinely ambiguous: either choice is correct
load(Overloaded::genuinelyAmbiguous); // <-- ERROR
Supplier s1 = Overloaded::genuinelyAmbiguous;
Processor p1 = Overloaded::genuinelyAmbiguous;
}
我们得到的错误是完全有道理的;可以将参数分配给任一参数,因此我们得到一个错误,指出方法调用不明确。load()
相反,如果我有一个看起来像这样的方法:
// Exhibit B
public static void exhibitB() {
// Correctly infers the right overloaded method
load(Overloaded::notAmbiguous);
Supplier s2 = Overloaded::notAmbiguous;
Processor p2 = Overloaded::notAmbiguous; // <-- ERROR
}
调用很好,并且正如预期的那样,我无法将方法引用分配给两者,并且因为它没有歧义:不能分配给。load()
Supplier
Processor
Overloaded::notAmbiguous
p2
现在是奇怪的那个。如果我有这样的方法:
// Exhibit C
public static void exhibitC() {
// Complains that the reference is ambiguous
load(Overloaded::strangelyAmbiguous); // <-- ERROR
Supplier s3 = Overloaded::strangelyAmbiguous;
Processor p3 = Overloaded::strangelyAmbiguous; // <-- ERROR
}
编译器抱怨对 的调用是不明确的 (),但与附件 A 不同,我无法将方法引用同时分配给 和 。如果它真的是模棱两可的,我觉得我应该能够像在图表A中一样分配和两个重载参数类型,但是我在声明时得到了一个错误。图C中的第二个错误是有道理的,不能分配给,但如果它是不可分配的,为什么它仍然被认为是模棱两可的?load()
error: reference to load is ambiguous
Supplier
Processor
s3
p3
p3
error: incompatible types: invalid method reference
Overloaded::strangelyAmbiguous
Processor
方法引用推理似乎只在确定要选择哪个重载版本时查看功能接口的 arity。在变量赋值中,会检查参数的 arity 和类型,这会导致重载方法和变量赋值之间存在这种差异。
在我看来,这就像一个错误。如果不是,至少错误消息是不正确的,因为当两个选择之间只有一个是正确的时,可以说没有歧义。