问题描述
public void add(long... x){}
public void add(Integer... x){}
add(2);
这会产生错误...为什么拓宽和装箱都不会进行重叠?
this produces error...why overlaoding is not performed with both widening and boxing?
但是没有vararg的超载工作正常
but overloading without vararg works fine
public void add(long x){}
public void add(Integer x){}
add(2);
这里添加(长x)将执行加宽节拍拳击...为什么不相同的概念使用
var参数
here add(long x) will be executed that is widening beats boxing...why not same concept withvar arguments
推荐答案
Java编译器执行三次尝试以选择适当的方法重载():
Java compiler performs three attempts to choose an appropriate method overload (JLS §15.12.2.1):
-
阶段1:识别匹配的Aric方法适用于子类型化
(可能的装箱转换和使用varargs的方法被忽略)
Phase 1: Identify Matching Arity Methods Applicable by Subtyping
(possible boxing conversions and methods with varargs are ignored)
阶段2:确定方法适用的匹配Arity方法
调用转换
(在帐户中进行装箱转换,但忽略varargs的方法)
Phase 2: Identify Matching Arity Methods Applicable by MethodInvocation Conversion
(takes boxing conversion in account, but ignores methods with varargs)
阶段3:确定适用的变量Arity方法
(检查所有可能性)
Phase 3: Identify Applicable Variable Arity Methods
(examines all possibilities)
因此,使用您的示例,它的工作原理如下:
So, with your examples it works as follows:
-
没有var args:
add(long x)
被识别为第一阶段唯一适用的方法(此方法适用于子类型,因为int
是long
的子类型,),以便不执行以下阶段。
Without varargs:
add(long x)
is identified as the only applicable method on the 1st phase (this method is applicable by subtyping sinceint
is a subtype oflong
, §JLS 4.10.1), so that following phases are not executed.
使用varargs :重载解析算法进入第3阶段,其中两种方法都被识别为适用,并且编译器无法选择最具体的方法(选择最具体的方法是另一种复杂算法),因此它报告歧义。
With varargs: overload resoltion algorithm goes to phase 3, where both methods are identified as applicable, and compiler can't choose the most specific method of them (choosing the most specific method is yet another complex algorithm), therefore it reports ambiguity.
参见:
- The Java Language Specification, Seventh Edition
这篇关于用加宽和拳击重载的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!