我有以下類:正在返回類型通用相同的擦除二進制兼容?
public abstract Foo {
Foo() {}
public abstract Foo doSomething();
public static Foo create() {
return new SomePrivateSubclassOfFoo();
}
}
我想將其更改爲以下定義:
public abstract Foo<T extends Foo<T>> {
Foo() {}
public abstract T doSomething();
public static Foo<?> create() {
return new SomePrivateSubclassOfFoo();
}
}
這是改變二進制兼容的? 也就是說,將編譯的版本與新版本的舊版本一起編譯而不重新編譯?
我知道我需要更改SomePrivateSubclassOfFoo
,這沒關係。我也知道這個改變會在編譯舊客戶端代碼時觸發原始類型的警告,這對我也是可以的。我只是想確保舊客戶端代碼不需要重新編譯。
根據我的理解,這應該是可以的,因爲T
的刪除是Foo
,因此字節碼中的doSomething
的簽名與之前相同。如果我查看由javap -s
打印的內部類型簽名,我確實看到了這一點(雖然在不使用-s
時打印的「非內部」類型簽名確實不同)。 我也測試過這個,它對我有用。
但是,Java API Compliance Checker告訴我,這兩個版本不是二進制兼容的。
那麼什麼是正確的? JLS在這裏保證二進制兼容性,還是在測試中我只是幸運的? (爲什麼會發生這種情況?)