2015-11-21 38 views
7

注:我發現了多個指出javac與Eclipse編譯器之間差異的問題,但據我所見,他們都討論了其他問題。泛型和lambdas - 在javac和Eclipse編譯器中的不同行爲

假設我們有這樣的方法:編譯調用此方法的時候,我不知道哪兩個是正確

public static <T, U> void foo(Supplier<T> a, Function<T, U> b, Consumer<U> c) 
{ 
    c.accept(b.apply(a.get())); 
} 

我發現javac之間不同的行爲和Eclipse Java編譯器。


一個簡單的使用這種方法可以是:

// variant 1 
foo(
    () -> Optional.of("foo"), 
    value -> value.get(), 
    value -> System.out.println(value)); 

編譯器應該能夠使用第一參數和U使用第二結合TOptional<String>String。所以這個電話應該是有效的(在我看來)。

編譯沒有使用javac,但無法使用Eclipse編譯:

類型不匹配:不能從空轉變爲<未知>

添加一個類型參數的第一個參數(() -> Optional.<String> of("foo"))也使它在Eclipse中編譯。

問題:從規範的角度來看,Eclipse拒絕這個調用是否正確(以及爲什麼(不))?


現在假設我們想拋出一個自定義(運行時)例外,如果Optional爲空:

// variant 2 
foo(
    () -> Optional.of("foo"), 
    value -> value.orElseThrow(() -> new RuntimeException()), 
    value -> System.out.println(value)); 

這是由雙方拒絕,javac和Eclipse編譯器,但使用不同的錯誤信息:

  • javac: 「沒有報告異常X;必須捕獲或聲明拋出」
  • Eclipse的編譯器:「類型不匹配:不能從空轉變爲<未知>」

當我添加類型參數的第一個參數如上,Eclipse的成功編制,同時javac仍然失敗。當我在第二個參數中添加<RuntimeException>作爲類型參數時,反過來,Eclipse失敗並javac成功。

問題:再說一次,編譯器是否有權拒絕這個調用,爲什麼?


在我看來,這兩個變種應該編譯罰款沒有額外的提示通過使用類型參數。如果是這樣,我將爲javac(關於「未報告的異常」)和Eclipse編譯器(關於「類型不匹配」)填寫一個錯誤報告。但首先我想確保規範與我的觀點一致。

版本中使用:

  • javac:1.8.0_66
  • 的Eclipse JDT:3.11.1.v20151118-1100

編輯:

我填針對Eclipse中的問題的bug 482781

javac的問題已被報告爲JDK-8056983,請參閱Tunakis answer

+1

有疑問時會責怪日食:)類型推斷非常複雜,整個lambda語法還是相當新的。 Eclipse有幾個修正的錯誤,但是在當前的發行版中留下了一些錯誤,與此類邊緣案例有關。 – zapl

+1

當涉及到通用擴展時,Eclipse Mars ECJ編譯器與最新的Luna相比確實很麻煩。當ECJ 3.11失敗或者甚至陷入無限循環而javac和ECJ 3.10編譯正確時,我已經發現至少有三種情況。這就是爲什麼我還在使用Luna。 –

+0

Eclipse bug已經通過https://bugs.eclipse.org/470826修復了4.6 M1,它也被安排到mars.2的back端口 –

回答

5

是的,你在任何方面都是對的。老實說,我不能鏈接到JLS的特定行:關於這個:type推斷is a whole chapter

聲明:我使用Eclipse Mars 4.5.1和JDK 1.8.0_60進行了測試。


變1應編制和Eclipse這裏有一個錯誤。我在他們的Bugzilla中找不到與此相關的任何內容,所以您可以繼續並歸檔。你可以保證自己,它,如果你減少你的例子,這應該編譯:

public static <T> void foo(Supplier<T> a) { 
    a.get(); 
} 

foo(() -> Optional.of("foo")); 

編譯沒有問題都與Eclipse和javac。在編譯期間添加參數確實(應該)不會改變T推斷的類型。


變2不編譯javac,這確實是一個錯誤,如JDK-8056983報道。編譯器應該能夠推斷出XRuntimeException。至於爲什麼Eclipse仍然無法編譯這個,再一次,我在他們的Bugzilla中找不到任何東西,所以請隨時舉報!

+1

https://bugs.eclipse.org/470826的修復程序可讓Eclipse接受兩種變體。 –

相關問題