Пример (игнорируйте уродливое :
Код: Выделить всё
public interface Entity {
boolean a();
}
public interface Intf1 {
Entity entity();
}
public interface Main {
Intf1 intf();
}
Код: Выделить всё
public interface ExtendedEntity extends Entity {
boolean b();
}
public interface Intf2 extends Intf1 {
ExtendedEntity entity();
}
public interface Main {
Intf2 intf();
}
Я хотел бы добавить в Main метод с другим типом возвращаемого значения. Два метода (один, возвращающий супертип, и другой, возвращающий подтип) должны быть сопоставлены с одним и тем же методом реализации (который возвращает подтип). Примечание. Насколько я понимаю, это разрешено JVM, но не спецификацией Java.
Мое решение, которое похоже работает злоупотребляет (у меня нет другого слова для этого) системой классов Java для добавления необходимого интерфейса.
Код: Выделить всё
public interface Main_Backward_Compatible {
Intf1 intf();
}
public interface Main extends Main_Backward_Compatible{
Intf2 intf();
}
Это похоже работает. Во всех тестах, которые я мог придумать (за исключением отражения — но меня это не волнует), это работало.
Будет ли это работать всегда? Верны ли мои рассуждения (по поводу ignorevirtual)?
И еще один, связанный с этим вопрос — существуют ли инструменты для проверки «реальной» бинарной совместимости? Единственные, которые я нашел, рассматривают каждый метод отдельно, но не учитывают иерархию типов.
Спасибо,
Ран. p>
Редактирование — инструменты, которые я пробовал и нашел «не очень хорошими» (не принимать во внимание иерархию типов):
< ol>
[*]Clirr 0.6.
[*]Плагин IntelliJ «APIComparator».
Edit2 — Конечно, моим клиентам запрещено создавать классы реализации для моих интерфейсов (например, сервисов). Однако, если вы хотите, чтобы пример был полным, подумайте об абстрактном классе (для Main) вместо интерфейса.
Подробнее здесь: https://stackoverflow.com/questions/349 ... rn-type-us