Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/356.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/22.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/jquery-ui/2.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 确切的重载解析过程-为什么f(1)对f(int…arg)和f(long…arg)的调用不含糊?_Java_Variadic Functions_Method Invocation_Ambiguous Call - Fatal编程技术网

Java 确切的重载解析过程-为什么f(1)对f(int…arg)和f(long…arg)的调用不含糊?

Java 确切的重载解析过程-为什么f(1)对f(int…arg)和f(long…arg)的调用不含糊?,java,variadic-functions,method-invocation,ambiguous-call,Java,Variadic Functions,Method Invocation,Ambiguous Call,我觉得这些都是适用的: JLS。阶段3:通过变量确定适用的方法 算术调用 JLS选择最具体的方法 但是JLS语言太复杂了,我无法理解这一点 void f(Integer... arg) { System.out.println("Integer..."); } void f(int... arg) { System.out.println("int..."); } void test() { f((short)1); // int... called f(1); // c.

我觉得这些都是适用的:

JLS。阶段3:通过变量确定适用的方法 算术调用

JLS选择最具体的方法

但是JLS语言太复杂了,我无法理解这一点

void f(Integer... arg) { System.out.println("Integer..."); }

void f(int... arg) { System.out.println("int..."); }

void test() {
    f((short)1); // int... called 
    f(1); // c.ERR
我似乎理解其中一个(除此之外,这个问题已经得到了回答),尽管答案没有描述整个重载解析过程的所有细节(确切的顺序-尝试了哪些参数)-无论如何,我的问题主要在第二个代码段(int..vs long…)中。但让我详细介绍一下上述片段:

f((short)1)
-无精确匹配,因此先加宽原始short(未找到匹配项),然后将short装箱为short(未找到精确匹配项),加宽short(数字、对象)-无匹配,现在进入第三阶段(varargs)=>尝试以下操作:

  • 短。。。(无精确匹配=>尝试基本体加宽)
  • 内。。。(找到了精确的匹配项,但不要停止,请进一步搜索!)
  • 长…,浮动…,双。。。(不匹配=>尝试拳击)
  • 短…,数字…,对象
由于未找到其他匹配项,因此编译正常

f(1)
-无精确匹配,因此先加宽原始int(未找到匹配),然后将int装箱为整数(未找到精确匹配),加宽整数(数字,对象)-无匹配,现在进入第三阶段(varargs)=>尝试以下操作:

  • 内。。。(找到了精确的匹配项,但不要停止,请进一步搜索!)
  • 长…,浮动…,双。。。(不匹配=>尝试拳击)
  • 整数。。。(现在不明确),数字…,对象
由于找到了两个可能的匹配项,我们有一个编译错误

void f(long... arg) { System.out.println("long..."); }

void f(int... arg)  { System.out.println("int..."); }

void test() {
    f((byte)1); // int... called 
    f(1);       // int... called 
}
f(字节)
-第三阶段(varargs)=>尝试了以下步骤:

  • 字节。。。(不匹配=>尝试基本体加宽)
  • 短…,内。。。(找到匹配项,但请进一步查看),长。。。(应该是模糊错误,但不是!)、浮点…、双精度。。。(现在还进行装箱,随后扩展引用,以寻找更多可能的匹配项,从而将编译错误标记为“不明确”)
  • 字节…,数字…,对象
如果找到两个可能的匹配项,则应为编译错误(但事实并非如此)

我的猜测是有4个过程(精确原语匹配、原语加宽、装箱和精确引用匹配、引用加宽),如果编译器在某个过程中发现匹配(该过程不继续),它将停止,但会尝试所有其他后续过程。在本例中,编译器在过程2停止(仅int…匹配,但不是long…),过程3和4没有生成匹配

上述SO报价提供了以下标准:

如果一个参数比另一个参数更具体,则 该参数必须是其他方法参数的子类型

它可能适用于引用类型,但不适用于原语

我似乎理解编译时步骤2:确定方法签名。但在我的例子中,我们有“第三阶段(§15.12.2.4)允许重载与变量算术方法、装箱和拆箱相结合。”——但这方面的细节是问题所在

至于评论

如果一个参数比另一个参数更具体,则该参数的类型 参数必须是其他方法参数的子类型

请注意,这适用于基本类型,请参见 规范中给出的关系意味着int是比long更具体的类型

对于任何表达式,如果S@CodeComplete是,则类型S比类型T更具体,因此它“解决”了歧义问题,对吗?因为int比long更具体,所以方法f(int…)比f(long…)更具体。因此f(int…)是将被调用的方法。