Существует важное различие между исходной совместимостью и двоичной совместимостью.
- Если две версии некоторого класса V1 и V2 двоично совместимы, это означает, что классы, скомпилированные с V1, будут прекрасно работать с V2.
- Если две версии некоторого класса V1 и V2 совместимы с исходным кодом, это означает, что класс, который может скомпилироваться с V1, будет прекрасно скомпилирован с V2.
Совместимость с исходным кодом делает not автоматически подразумевает двоичную совместимость, как вы уже видели.
Когда исходный код компилируется, определенная сигнатура метода, которая должна быть вызвана, определяется компилятором и сохраняется в файле .class
(в данном случае это doSomething(List)
).
Если класс изменяется и метод doSomething(List)
удаляется при добавлении doSomething(Collection)
, то совместимость с исходным кодом сохраняется (поскольку вы можете просто скомпилировать тот же код дляновый класс), но двоичная совместимость потеряна!
Спецификация языка Java имеет Весь раздел о двоичной совместимости .
Подводя итог: при изменении типа аргумента метода на более общий тип (обычно) совместим с источником, он не двоично совместим.
Если вы хотите сохранить двоичную совместимость, то изменение должно выглядеть следующим образом:
public void doSomething(Collection foo) { ... } // original method with changed argument type
public void doSomething(List foo) { // new binary compatibility method, just delegates to original one
doSomething((Collection) foo);
}