Java - совместимость на уровне двоичных кодов абстрактного класса и подклассов

В Java я определяю абстрактный класс и с конкретными и с абстрактными методами в нем, и он должен быть разделен на подклассы независимо сторонними разработчиками. Только быть уверенным: есть ли какие-либо изменения, которые я мог внести в абстрактный класс, которые являются источником, совместимым с их классами, но не двоичные совместимый? Другими словами: после того, как они скомпилировали свои подклассы, я мог изменить абстрактный класс - кроме, например, добавление абстрактного метода для него или удаление защищенного метода от него, который называют подклассы, которые являются, конечно, несовместимым источником - способом, который мог вынудить их перекомпилировать свои подклассы?

6
задан thSoft 14 May 2010 в 22:07
поделиться

3 ответа

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

9
ответ дан 8 December 2019 в 14:41
поделиться

Я предполагаю, что вы используете "бинарную несовместимость" в техническом смысле; например, когда загрузчик классов обнаруживает несовместимость и отказывается загружать классы.

Бинарная несовместимость также может возникнуть, если вы добавите видимый метод и объявите его final, и этот метод столкнется с сигнатурой некоторого существующего метода в стороннем подклассе. Однако, если метод не финальный, существующий метод превратится в переопределение вашего (нового) метода, что может вызвать проблемы... но не бинарную несовместимость.

Аналогично, добавление новых видимых полей приведет к скрытию, может привести к запутанному поведению и нарушит сериализацию объекта. Но это не приведет к бинарной несовместимости.

В целом это указывает на то, что вам необходимо учитывать семантические вопросы приложения, а также простую бинарную совместимость. И система типов Java вам в этом не поможет.

Для полноты картины, есть и другие вещи, которые вы можете сделать в своем коде, которые нарушат бинарную совместимость для сторонних классов:

  • уменьшить видимость вашего абстрактного класса и/или его методов,
  • изменить сигнатуры других классов, используемых в качестве результатов параметров и типов исключений,
  • изменить цепочку суперклассов, которые расширяет ваш абстрактный класс, или внести несовместимые изменения в эти классы, или
  • изменить дерево интерфейсов, которые реализует ваш абстрактный класс, или внести несовместимые изменения в эти интерфейсы.
5
ответ дан 8 December 2019 в 14:41
поделиться

Конечно.

Вы можете случайно использовать имя метода, которое они использовали, но теперь оно внезапно переопределено, что может привести к совершенно другим результатам.

Вы можете добавить в класс поля, которые нарушают сериализацию и т. Д.

2
ответ дан 8 December 2019 в 14:41
поделиться
Другие вопросы по тегам:

Похожие вопросы: