2011-10-02 23 views
8

我有相關的下面的代碼片段一個問題:Java的問題與VAR-指定參數和拳擊

class VarArgsTricky { 
    static void wide_vararg(long... x) { 
     System.out.println("long..."); 
    } 

    static void wide_vararg(Integer... x) { 
     System.out.println("Integer..."); 
    } 

    public static void main(String[] args) { 
     int i = 5; 
     wide_vararg(i, i, i); // needs to widen and use var-args 
     Long l = 9000000000l; 
     wide_vararg(l, l); // prints sucessfully "long..." 
    } 
} 

到wide_vararg第一次調用編譯失敗(他說,該方法是ambigous),而第二編譯剛精細。

對此行爲的任何解釋? 謝謝!

+0

如果這不僅僅是一個關於重載的實驗,請閱讀Effective Java SE:項目41明智地使用重載。 – TJR

+0

這純粹是一個實驗,只是爲了解決OCPJP認證考試的潛在問題。 –

回答

1

當調用var-arg方法時,參數會在編譯時轉換爲該類型的數組。

在第一次調用中,參數被轉換爲int []。由於Java中的所有數組都是Object類的直接子類型,因此基本擴展的概念不適用,在這種情況下,由於long []和Integer []處於同一級別,所以重載同時適用。因此,含糊不清

10

第一wide_vararg呼叫是不明確的,因爲編譯器可以

  • 加寬int s至long S,並調用所述第一wide_vararg方法,
  • autobox的int s到Integer s,並撥打第二個wide_vararg

它不知道它應該做,然而,它拒絕編譯曖昧方法調用。如果要第一次調用,請將i聲明爲Integerlong,而不是int

+1

根據K&B SCJP 6書加寬拳擊拳擊節奏變異參數。所以第一個電話應該選擇擴大而不是自動包裝。如果我被聲明爲一個整數,它也不會編譯。當然,漫長的工作。問題仍然存在:爲什麼它不選擇擴大自動裝箱? –

+0

嗯,你是對的。我不確定爲什麼。哎呀,這可能是一個編譯器錯誤。然而,可變長參數是否被擴大或拳擊打敗是一個不容置疑的問題,因爲沒有非可變參數選擇。 –

+1

沒有非可變參數選擇,這是真的。它可能是某種編譯器錯誤或一些鮮爲人知的功能。準確地知道這將是有趣的。 –