为什么这个Java方法调用被认为是不明确的?
我遇到了一个奇怪的错误消息,我认为可能是不正确的。考虑下面的代码:为什么这个Java方法调用被认为是不明确的?,java,overloading,method-reference,functional-interface,arity,Java,Overloading,Method Reference,Functional Interface,Arity,我遇到了一个奇怪的错误消息,我认为可能是不正确的。考虑下面的代码: 公共类重载{ 公共接口供应商{ int get(); } 公共接口处理器{ 字符串进程(字符串s); } 公共静态空荷载(供应商){} 公共静态无效负载(处理器p){} public static int true-yambioguous(){return 4;} 公共静态字符串真正双向(字符串s){返回“字符串”;} public static int notAmbiguous(){return 4;} 公共静态字符串notA
公共类重载{
公共接口供应商{
int get();
}
公共接口处理器{
字符串进程(字符串s);
}
公共静态空荷载(供应商){}
公共静态无效负载(处理器p){}
public static int true-yambioguous(){return 4;}
公共静态字符串真正双向(字符串s){返回“字符串”;}
public static int notAmbiguous(){return 4;}
公共静态字符串notAmbiguous(intx,inty){返回“字符串”;}
公共静态int奇怪地有歧义(){return 4;}
公共静态字符串奇怪地有歧义(intx){返回“字符串”;}
}
如果我有一个如下所示的方法:
//附件A
公共静态无效参展商A(){
//真正模棱两可:任何一种选择都是正确的
加载(重载::真正的模糊);//你的问题与一个非常相似
简单的回答是:
Overloaded::genuinelyAmbiguous;
Overloaded::notAmbiguous;
Overloaded::strangelyAmbiguous;
所有这些方法引用都是不精确的(它们有多个重载)。因此,根据,在重载解析期间,它们被从适用性检查中跳过,从而导致歧义
在这种情况下,需要显式指定类型,例如:
load((Processor) Overloaded::genuinelyAmbiguous);
load(( Supplier) Overloaded::strangelyAmbiguous);
方法引用和重载,只是…不要。理论上,您完全正确-这对于编译器来说应该是相当容易推断的,但我们不要混淆人和编译器
编译器看到对load
的调用,并说:“嘿,我需要调用该方法。很酷,可以吗?有两个。当然,让我们匹配参数”。参数是对重载方法的方法引用。因此编译器在这里非常困惑,它基本上说:“如果我能说出你所指向的方法引用,我可以调用load
,但是,如果我能说出你想调用的load
方法,我可以推断出正确的奇怪的含糊不清的”,因此它只是在兜圈子,追逐它的故事。这在编译器的头脑中做出了决定“这是我能想到的解释它的最简单的方法。这带来了一个非常糟糕的做法-方法重载和方法引用是一个坏主意
但是,您可能会说-ARITY!当编译器决定这是否是重载时,参数的数量是(可能)要做的第一件事,这正是您的观点:
Processor p = Overloaded::strangelyAmbiguous;
对于这个简单的例子,编译器确实可以推断出正确的方法,我的意思是,我们人类可以,对于编译器来说应该是一个不需要动脑筋的人。这里的问题是,这是一个只有两种方法的简单例子,那么100*100的选择呢?设计者必须要么允许某种方法(比如5*5,并允许这样的分辨率)或者完全禁止这种做法——我想你知道他们的做法。如果你使用lambda,那么这一点应该很明显,因为lambda arity就在那里,是明确的
关于错误消息,这并不是什么新鲜事,如果您充分使用lambda和方法引用,您将开始讨厌错误消息:“不能从静态上下文引用非静态方法”IIRC这些错误消息在java-8和更高版本中得到了改进,您永远不知道java-15中的错误消息是否也会得到改进,比如说。我可以复制,但请您删除“附件A”和“附件B”好吗?我认为,它们并没有真正增加对问题的理解。图表C本身就很好。请记住,人类必须维护这段代码。即使编译器能够理解它,我也更喜欢像loadProcessor
和loadSupplier
这样的名称,所以我不必考虑它。@markspace记住,作为human、 我们想了解它实际上是如何发生的works@ArnaudClaudel是的,我知道,这就是为什么它是一个评论,而不是一个答案。问这个问题很好,但这个问题主要是学术性的。我希望没有人以这种方式编写生产代码。