多参数重载函数

问题描述:

我已阅读,在方法重载,优先进入的事实:多参数重载函数

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

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

例如:

代码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 

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

那么,在第一种情况下,第一种方法有一个参数需要加宽,另一个是完全匹配。第二种方法有一个参数完全匹配,另一个需要装箱。由于加宽优先于拳击,因此选择第一种方法。

在第二种情况下,第一种方法有可变参数,而第二种方法需要装箱和加宽。由于扩展和装箱优先于可变参数,因此选择第二种方法。

你能想出例子,其中它不会是清楚选择哪种方法:

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

在这种情况下,第一种方法对第一个参数的优先级,而第二种方法的优先级为第二个论点。因此,编译器无法在它们之间进行选择,编译将失败。

+0

公共静态无效overloadResolve(长我,诠释... j)的 { } 公共静态无效overloadResolve(INT I,对象o){ } – user2653926 2014-10-30 08:26:49

+0

这个怎么样 – user2653926 2014-10-30 08:27:38

+0

@ user2653926可变参数总是有最低的优先顺序,所以第二个会被选中 – Eran 2014-10-30 08:29:58

在第二种情况下,因为最后一个优先级是可变参数,所以在它之前它将Auto Boxing(int转换为Integer-first参数)和Widening转换为第二个参数(int转换为long)。作为最后优先级的可变参数,它选择call 2

正如你所说,优先顺序是精确匹配>加宽>装箱/拆箱>可变参数。下面是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 i in到long 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. 加宽第二个参数int i in到long i和Boxing第一个参数int iInteger i匹配public static void overloadResolve(Integer i,long o),我们称之为!

因此,基本上,您可以为每个参数应用优先级顺序,直到它匹配其中一个重载的特征。

在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){} 

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