在將代碼庫從Java 1.7遷移到1.8期間,我們收到錯誤消息「方法...不適用於參數「在幾個代碼位置上,都遵循泛型使用中的相同模式。Java 8泛型此方法不適用於Eclipse中的參數
我們目前在Windows 7
上大多使用Eclipse Mars
(4.5.2),但也可以用Neon
(4.6)確認行爲。 Javac
以及ecj
與1.7合規性級別都可以編譯我們的代碼沒有錯誤。
這裏是一個最小的,完整的,並且可驗證例如:
public class ComplexInterfaceTest {
public static class Foo {}
public interface Bar {
void print();
}
public static class SubFooBar extends Foo implements Bar {
public void print() {
System.out.println(this.getClass().getSimpleName());
}
}
public static class FooBar<T extends Foo & Bar> {
public static <T extends Foo & Bar> FooBar<T> makeFooBar() {
return new FooBar<>();
}
public void create(T value) {
value.print();
return;
}
}
public static class Base<T extends Foo> {}
public static class Subclass extends Base<SubFooBar> {
public void doSomething(SubFooBar value) {
// FooBar.<SubFooBar>makeFooBar().create(value);
FooBar.makeFooBar().create(value);
}
}
public static void main(String[] args) {
new Subclass().doSomething(new SubFooBar());
}
}
現在doSomething
方法切換註釋掉的行會使代碼編譯,所以我們有一個解決方法。仍然錯誤消息似乎不正確,因爲類SubFooBar
延伸Foo
和執行Bar
,所以它履行<T extends Foo & Bar>
,這是<T extends Foo & Bar> FooBar<T> makeFooBar()
所需的合同,所以實際上T
IMO應綁定到SubFooBar
。
我搜索了類似的問題,發現這些: Differences in type inference JDK8 javac/Eclipse Luna? Type Inference Compiler Error In Eclipse with Java8 but not with Java7
這讓我覺得這可能是一個ecj
錯誤。在這個過程中我也看了成Eclipse Bugzilla
但找不到任何可比性,我看到了這些:
- 430686驗證固定的 - 我的是不是
- 440019有標量型做的事 - 我的不
- 492838,448793與通配符做的事情 - 我的不
現在Eclipse Bugzilla
討論都充滿了對ecj
的內部工作,我並不總是可以遵循的細節。我的理解雖然是普遍的共識,Eclipse
編譯器必須嚴格遵循JLS
而不是javac
(如果它是錯誤的),所以它不一定是ecj
中的錯誤。如果它不是ecj
錯誤,則編譯代碼必須是javac
錯誤。
我感興趣的是 - 對於那些可以分析我的代碼片段的類型推斷過程 - 應該代碼編譯還是編碼出錯?
編輯
正如我答應後我的報告到Eclipse的Bugzilla
結果:缺陷的ID爲#497905(斯蒂芬·赫爾曼已經張貼在接受的答案低於他的評論的鏈接),目前針對v4.7。
我剛剛發佈了一個關於Eclipse Bugzilla的bug報告,會在這裏發佈他們的答案。 –