2014-10-30 86 views
0

我已閱讀,在方法重載,優先進入的事實:多參數重載函數

精確匹配>拓寬>裝箱/拆箱>可變參數

這偉大工程只有一個參數的函數。但是對於有多個參數的函數,有時會給出奇怪的結果,大概是因爲我無法正確應用這個規則。

例如:

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

你能解釋一下如何在超載的情況下處理多個參數的函數?

回答

1

那麼,在第一種情況下,第一種方法有一個參數需要加寬,另一個是完全匹配。第二種方法有一個參數完全匹配,另一個需要裝箱。由於加寬優先於拳擊,因此選擇第一種方法。

在第二種情況下,第一種方法有可變參數,而第二種方法需要裝箱和加寬。由於擴展和裝箱優先於可變參數,因此選擇第二種方法。

你能想出例子,其中它不會是清楚選擇哪種方法:

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

1

在第二種情況下,因爲最後一個優先級是可變參數,所以在它之前它將Auto Boxing(int轉換爲Integer-first參數)和Widening轉換爲第二個參數(int轉換爲long)。作爲最後優先級的可變參數,它選擇call 2

1

正如你所說,優先順序是精確匹配>加寬>裝箱/拆箱>可變參數。下面是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),我們稱之爲!

因此,基本上,您可以爲每個參數應用優先級順序,直到它匹配其中一個重載的特徵。

1

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

由於最高可用優先拉大,選擇第二種方法。