я следующий класс:Является ли тип возвращаемого типа общим с одинаковым двоичным совместимым стиранием?
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();
}
}
Является ли это изменение двоичным совместимы? I.e., будет ли код, который скомпилирован против старой версии работы класса с новой версией без повторной публикации?
Я знаю, что мне нужно изменить SomePrivateSubclassOfFoo
, это нормально. Я также знаю, что это изменение вызовет предупреждения о необработанных типах при компиляции старого кода клиента, это тоже нормально для меня. Я просто хочу убедиться, что старый код клиента не нужно перекомпилировать.
Из моего понимания, это должно быть в порядке, потому что стирание T
является Foo
, и, таким образом, подпись doSomething
в байт-код такой же, как и раньше. Если я посмотрю на внутренние тиковые подписи, напечатанные javap -s
, я действительно вижу, что это подтверждено (хотя подписи типа «не внутренние», напечатанные без -s
, отличаются). Я тоже проверил это, и это сработало для меня.
Однако, Java API Compliance Checker сообщает мне, что две версии не совместимы с бинарными.
Итак, что именно? Является ли JLS гарантией двоичной совместимости здесь, или мне просто повезло в моих тестах? (Почему это могло случиться?)