jig*_*wot 15 java overloading arity functional-interface method-reference
我遇到了奇怪的错误消息,我认为这可能是不正确的。考虑以下代码:
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"; }
}
Run Code Online (Sandbox Code Playgroud)
如果我有一个看起来像这样的方法:
// Exhibit A
public static void exhibitA() {
// Genuinely ambiguous: either choice is correct
load(Overloaded::genuinelyAmbiguous); // <-- ERROR
Supplier s1 = Overloaded::genuinelyAmbiguous;
Processor p1 = Overloaded::genuinelyAmbiguous;
}
Run Code Online (Sandbox Code Playgroud)
我们得到的错误是很合理的;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
}
Run Code Online (Sandbox Code Playgroud)
的调用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
}
Run Code Online (Sandbox Code Playgroud)
编译器抱怨对的调用load()是模棱两可的(error: reference to load is ambiguous),但与图表A不同,我无法将方法引用分配给Supplier和Processor。如果确实是模棱两可,我觉得我应该能够像在表A中一样分配s3和分配p3这两种重载的参数类型,但是在p3声明这一点时出现错误error: incompatible types: invalid method reference。图表C中的第二个错误是有道理的,Overloaded::strangelyAmbiguous 不可分配给Processor,但如果不可分配,为什么仍被认为是模棱两可的?
在确定选择哪个重载版本时,方法引用推断似乎只考虑了FunctionalInterface的优点。在变量分配中,将检查参数的稀疏性和类型,这会导致重载方法与变量分配之间出现差异。
在我看来,这就像一个虫子。如果不是,则至少错误消息是不正确的,因为在两个选择之间只有一个是正确的时,可以说没有歧义。
您的问题与此非常相似。
简短的答案是:
Overloaded::genuinelyAmbiguous;
Overloaded::notAmbiguous;
Overloaded::strangelyAmbiguous;
Run Code Online (Sandbox Code Playgroud)
所有这些方法引用都不精确(它们有多个重载)。因此,根据JLS§15.12.2.2。,则会在重载解决期间将其从适用性检查中跳过,从而造成歧义。
在这种情况下,您需要明确指定类型,例如:
load((Processor) Overloaded::genuinelyAmbiguous);
load(( Supplier) Overloaded::strangelyAmbiguous);
Run Code Online (Sandbox Code Playgroud)