多参数重载函数(Multiple argument overloaded functions)

2019-10-21 05:30发布

我看过一个事实,即在方法的重载,优先去为:

精确匹配>拓宽>装箱/拆箱>可变参数

这个伟大的工程为只有一个参数的函数。 但对于有多个参数的功能这有时会给奇怪的结果,大概是因为我不能够正确地应用此规则。

例如:

代码1:

public static void overloadResolve(long i,int j){}      //1
public static void overloadResolve(int i,Integer o){}   //2
overloadResolve(5,6);                                   // calls 1

代码2:

public static void overloadResolve(int i,int... j){}    //1
public static void overloadResolve(Integer i,long o){}  //2 
overloadResolve(5,6);                                   // calls 2 

你能解释一下如何在超载的情况下处理多个参数的函数?

Answer 1:

Well, in the first case, the first method has one parameter that requires widening and another that is exact match. The second method has one parameter with exact match and another that requires boxing. Since widening has precedence over boxing, the first method is chosen.

In the second case the first method has varargs, while the second requires boxing and widening. Since both widening and boxing have precedence over varargs, the second method is chosen.

You could come up with examples where it wouldn't be clear which method to choose :

public static void overloadResolve(long i,Integer j){} //1
public static void overloadResolve(Integer i,long o){} //2
overloadResolve(5,6);

In this case the first method has precedence for the first argument, while the second method has precedence for the second argument. Therefore the compiler can't choose between them, and compilation would fail.



Answer 2:

在你的第二个情况下,因为最后的当务之急是可变参数,它通过自动拳击(INT到整数的第一个参数)和第二个参数拓展(INT长)在这之前。 凡为可变参数在最后优先它选择call 2



Answer 3:

正如你所说,优先顺序是精确匹配>强化>装箱/拆箱>可变参数。 下面是Java将做你蒙山例如:

public static void overloadResolve(long i,int j){}      //1
public static void overloadResolve(int i,Integer o){}   //2
overloadResolve(5,6); 
  1. 没有功能overloadResolve(int, int)所以没有精确匹配。
  2. 拓宽int ilong i匹配overloadResolve(long i,int j)让我们把它!

实施例2:

public static void overloadResolve(int i,int... j){}    //1
public static void overloadResolve(Integer i,long o){}  //2 
overloadResolve(5,6); 
  1. 没有功能overloadResolve(int, int)所以没有精确匹配。
  2. 拓宽第二ARG int ilong i和拳击第一个参数int iInteger i相匹配public static void overloadResolve(Integer i,long o)让我们把它!

所以基本上,你可以申请的优先顺序为每一个参数,直到它的一个重载的签名相匹配。



Answer 4:

在Java中重载方法选择过程进行了详细定义在这里: http://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.12.2并指出:

(...) uses the name of the method and the types of the argument expressions to 
locate methods that are both accessible and applicable, that is, 
declarations that can be correctly invoked on the given arguments.

There may be more than one such method, in which case the most specific one is chosen. 

如果没有深入的细节经历,声明most specific one is chosen你的情况可以归结为:

1. For all parameters identify their respective priority in method signature (based on the order you've defined) 
2. Choose lowest priority out of them for every method. 
3. Method with the highest resulting priority will be applied.

让我们来看看它是如何工作的还有你的代码:

overloadResolve(5,6); //Call with (int, int)

CODE1:

//(widening, exact) -> lowest priority: widening
public static void overloadResolve(long i,int j){}      
//(exact, autoboxing) -> lowest priority: autoboxing
public static void overloadResolve(int i,Integer o){}   

由于最高优先级的拉大,选择第一种方法

CODE2:

//(exact, vararg) -> lowest: vararg
public static void overloadResolve(int i,int... j){}    
//(autoboxing, widening) -> lowest: autoboxing
public static void overloadResolve(Integer i,long o){}  

由于最高可用优先拉大,选择第二种方法。



文章来源: Multiple argument overloaded functions