Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/389.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么这个Java方法调用被认为是不明确的?_Java_Overloading_Method Reference_Functional Interface_Arity - Fatal编程技术网

为什么这个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是的,我知道,这就是为什么它是一个评论,而不是一个答案。问这个问题很好,但这个问题主要是学术性的。我希望没有人以这种方式编写生产代码。