2017-09-04 117 views
7

考慮以下兩組方法。第一個被接受,第二個被拒絕爲模棱兩可。唯一的區別是使用int和Integer。對象和基元類型的模糊可變參數方法

是否有特別需要拒絕第二個?這意味着在拳擊後接受它(這將導致第一組)有問題。我在這裏錯過什麼?

從我的角度來看,Java編譯器在這裏太侷限了。

套裝1:

public void test(Object... values) {} 

public void test(Integer x, Object... values) {} // difference here 

public void b() { 
    test(1, "y"); // accepted 
} 

盤2:

public void test(Object... values) {} 

public void test(int x, Object... values) {} // difference here 

public void b() { 
    test(1, "y"); // marked as ambiguous 
} 

集2產生編譯器錯誤:

error: reference to test is ambiguous 
    test(1, "y"); // marked as ambiguous 
    ^
    both method test(Object...) in T and method test(int,Object...) in T match 

的Java 1.8,Eclipse的氧氣

+0

Set 1和Set 2的方法在同一個類中? –

+1

@RafaelVieiraCoelho當然不是。 – Kayaman

+0

同一班。我只是編輯班級在兩者之間進行更改。 –

回答

1

所不同的是在第一種情況下,t他需要將參數1裝箱成Integer,然後選擇最合適的方法;那就是(Integer, Object...)版本。

在第二種情況下,有兩個選項 - 裝箱或不。這是什麼讓它模糊。

我同意這是違反直覺的。

+0

我同意,編譯器正確實現了規範。我的觀點是Java編譯器可以在編譯時輕鬆解除這個限制:不需要複雜的分析。規範太嚴格了 –

5

編譯器正在執行JLS 15.12.2.5中規定的規則,以便在多個方法適用於調用的情況下選擇最具體的方法。在你的問題的例子,不同的是該行的規格涵蓋:

A type S is more specific than a type T for any expression if S <: T (§4.10).

其中S <: T意味着ST一個亞型。

在示例#1:

  • 有兩種適用的方法
  • 類型IntegerObject一個亞型,因此它是更具體的。
  • 因此,第二種方法比第一種更具體。
  • 因此選擇第二種方法。

在示例#2:

  • 有兩種適用的方法
  • 類型intObject或反之亦然的一個子類型,所以既不型比其他更具體的。
  • 因此,這兩種方法都比另一種更具體。
  • 因此調用是不明確的。
0

要解決這個問題,讓我總結我的問題的實際答案,因爲我瞭解他們:根據規範,行爲是正確的。規範可以放寬,以便原始類型被覆蓋爲非原始類型。尚未完成的一個原因是指定和實施快速正確的解析器的複雜性。

相關問題