Может ли удаление final из определения класса нарушить обратную совместимость? - PullRequest
6 голосов
/ 09 сентября 2010

В настоящее время я читаю «Эффективную Java» Джошуа Блоха, а пункт 17 - «Создай и документируй для наследования или запрети его».Автор предлагает запретить наследование по умолчанию.

Безопасно ли по умолчанию объявлять классы final и в более позднем выпуске удалить ключевое слово final, если есть необходимость расширить класс?Будет ли это нарушать обратную совместимость с кодом, который был скомпилирован с предыдущей версией?

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

Ответы [ 3 ]

10 голосов
/ 09 сентября 2010

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

Спецификация языка Java, §13.4.2 , имеет следующее, что сказать о двоичной совместимости:

Изменение класса, который был объявлен final, чтобы больше не объявляться final не нарушает совместимость с существующими ранее двоичными файлами.

Полагаю, вы все еще могли бы составить понятный пример, где он действительно может сломать программу; как генерация байт-кода класса, наследуемого от предположительно final класса, а затем загрузка этого сгенерированного класса и получение VerifyError.

2 голосов
/ 09 сентября 2010

Если вы разрабатываете что-то вроде Java Standard API, которое миллионы программистов будут использовать в течение многих лет, да, подумайте, как Джошуа Блох. ВПЕРЕД ЭВОЛЮЦИЯ имеет решающее значение.

99% программ на Java нет. Они разработаны для внутреннего использования, влияние изменения API незначительно, обычно весь исходный код доступен для рефакторинга. ПРОСТОТА является ключевой для таких программ. Если у вас сложный и причудливый дизайн или вы все время думаете о финале или нет, вы теряете время.

Я виню Джошуа за то, что он не установил надлежащих заявлений об отказе от ответственности за его предложения.

2 голосов
/ 09 сентября 2010

Мои мысли по этому поводу:

Удаление final в классе не вызовет немедленных проблем.Но учтите следующее:

Был финальный класс AdamsFactory, который вы изменили на не финальный.Через два месяца к вашей команде присоединился новый программист по имени Дилберт.
Он подклассирует ваш класс, который должен был быть финальным, в ScottFactory, но нарушает принцип замещаемости Лискова.

Затем ваш класс ComicStripPrinter использует ScottFactory вместо AdamsFactory.Что-то обязательно сломается.

Что возвращает нас к тому, что говорит Джошуа Блок:

Если вы намереваетесь наследовать: спроектируйте его с обдумыванием и задокументируйте.Если вы не намерены наследовать, то предотвратите его.

Надеюсь, то, что я сказал, не было большой нагрузкой.


РЕДАКТИРОВАТЬ:

Go предисловие Java Langauge Specification и поиск Джошуа Блоха:)

...