Бинарная совместимость Java - RFC о предлагаемом решении ковариантного типа возвращаемого значения с использованием сема ⇐ JAVA

Программисты JAVA общаются здесь
Anonymous
Бинарная совместимость Java - RFC о предлагаемом решении ковариантного типа возвращаемого значения с использованием сема

Сообщение Anonymous »

Я пытаюсь разработать API. В рамках этой эволюции мне нужно изменить тип возвращаемого значения метода на подкласс (специализироваться), чтобы продвинутые клиенты могли получить доступ к новой функциональности.
Пример (игнорируйте уродливое :

Код: Выделить всё

public interface Entity {
boolean a();
}

public interface Intf1 {
Entity entity();
}

public interface Main {
Intf1 intf();
}
Теперь я хочу иметь ExtendedEntity, Intf2 и Main вот так:

Код: Выделить всё

public interface ExtendedEntity extends Entity {
boolean b();
}

public interface Intf2 extends Intf1 {
ExtendedEntity entity();
}

public interface Main {
Intf2 intf();
}
Однако, поскольку тип возвращаемого значения метода является частью его сигнатуры, клиенты, уже скомпилированные с предыдущей версией кода, показывают ошибки связывания (метод не найден iirc).

Я хотел бы добавить в Main метод с другим типом возвращаемого значения. Два метода (один, возвращающий супертип, и другой, возвращающий подтип) должны быть сопоставлены с одним и тем же методом реализации (который возвращает подтип). Примечание. Насколько я понимаю, это разрешено JVM, но не спецификацией Java.

Мое решение, которое похоже работает злоупотребляет (у меня нет другого слова для этого) системой классов Java для добавления необходимого интерфейса.

Код: Выделить всё

public interface Main_Backward_Compatible {
Intf1 intf();
}

public interface Main extends Main_Backward_Compatible{
Intf2 intf();
}
Теперь старые клиенты будут иметь правильный метод, возвращаемый при поиске ignorevirtual (поскольку метод с правильным типом возвращаемого значения существует в иерархии типов) и реализацию, которая действительно будет работать будет тот, который возвращает подтип Intf2.

Это похоже работает. Во всех тестах, которые я мог придумать (за исключением отражения — но меня это не волнует), это работало.

Будет ли это работать всегда? Верны ли мои рассуждения (по поводу ignorevirtual)?

И еще один, связанный с этим вопрос — существуют ли инструменты для проверки «реальной» бинарной совместимости? Единственные, которые я нашел, рассматривают каждый метод отдельно, но не учитывают иерархию типов.

Спасибо,

Ран. p>

Редактирование — инструменты, которые я пробовал и нашел «не очень хорошими» (не принимать во внимание иерархию типов):

< ol>
[*]Clirr 0.6.
[*]Плагин IntelliJ «APIComparator».


Edit2 — Конечно, моим клиентам запрещено создавать классы реализации для моих интерфейсов (например, сервисов). Однако, если вы хотите, чтобы пример был полным, подумайте об абстрактном классе (для Main) вместо интерфейса.

Подробнее здесь: https://stackoverflow.com/questions/349 ... rn-type-us

Вернуться в «JAVA»