+1111 голосов |
То, что долго готовилось и должно было случиться, - случилось. Java 8 уже доступна, традиционно - для всех платформ. Попробую кратко обрисовать новое, но сконцентрирую внимание больше на эволюции Java, чем на подчёркивании каких-то "революционных" изменений.
Для начала - немного относительно "свежих" и очевидных фактов, объясняющих почему эволюция Java-платформы важна для IT в целом:
- несмотря на любые домыслы, Java остаётся платформой №1;
- количество разработчиков оценивается на уровне 9 миллионов;
- число загрузок Java (рантайм и JDK) - больше 1 миллиарда в год;
- количество Java-устройств в мире оценивается на уровне 3 миллиардов;
- 97% рабочих компьютеров из корпоративного сектора исполняют Java-приложения;
- Java прочто удерживает титул самой востребованной платформы в сегменте анализа данных.
Проверял я работу Java 8 SDK на двух машинах - одна под управлением Windows 8.1, вторая - Xubuntu 13.10, причём совсем слабенькая, она еле дышит под той же Windows 8.1. Выбор машин - умышленный, как и приложений. Java слишком обширна, чтобы ограничиваться только серверными приложениями, над платформой надстроен великолепный технологический стек для повседневного программистского, причём выходящего далеко за границы Java (например, среда разрабтки PyCharm для Python), и игнорировать эту составляющую никак нельзя.
Но детали - это не главное.
Итак, что же серьёзное случилось в Java 8 и как разработчики языка умудрились "вписать" это серьёзное в развитие платформы так, чтобы ничего не "сломать" во всём её прошлом?
Первое существенное изменение - расширение понятия "интерфейс". "Интерфейс" в Java всегда был специфическим абсолютно и безоговорочно абстрактным классом (и, соответственно, довольно самостоятельным типом). То есть, классом, который без дополнительной и явно выполненной программистом реализации "всего" принципиально не может быть "овеществлён" (instantiated). Именно эту специфику и подчеркнули отдельным ключевым словом языка interface. И это фундаментальная особенность системы типов Java, на которой выстроенна вся развитая иерархия типов.
Попробую объяснить проще - "интерфейс" в Java мог содержать только константы и описания методов (функций). Без всякой реализации. "Овеществить" такое (создать объект такого типа), очевидно, без явной реализации всего, что существует только на уровне описаний, невозможно. И нужно всё это для описания "набора правил поведения" будущих объектов классов, реализующих интерфейс. Как программист реализует следование "правилам поведения" - его личное дело, интерфейс же гарантирует соблюдение объектом этих правил. Поэтому можно считать интерфейс неким соглашением (контрактом) с внешним по отношению к реализующим его объектам, миром.
С помощью интерфейсов в Java всегда компенсировалась (и очень разумно) "врождённая недостаточность" множественного наследования, которого язык принципиально не поддерживает. В общем, интерфейсы - фундаментальная и одна из главнейших концепций Java.
Java 8 внесла существенную корректировку в эту концепцию. начнём с того, что теперь "интерфейс" может быть как бы частично абстрактным, потому что в Java 8 появились "методы интерфейсов, определённые по умолчанию" (interface default methods), а также статические методы.
Default methods - конструкция, которая, по идее, нужна была давно. Без неё научились обходиться и сформировали разные приёмы проектирования и реализации, но если есть возможность избежать лишнего - лучше его избежать (собственно, это и особенно привлекательно в модификациях интерфейсов Java 8 - все они явно подсказаны практикой и накопленным опытом). Предпосылкой необходимости default methods стал очевидный вопрос: если "интерфейс" - это де-факто контракт, то что произойдёт с его реализацией и со всеми "подписантами" в случае изменения контракта? Программные системы ведь эволюционируют, и уровень проектирования "до самых мелочей" возможет только в очень специфических случаях. Этот вопрос сам по себе неприятен на уровне работы с исходными кодами, но ещё же есть бинарное представление программ и крайне неприятная, но нужная в реальности "бинарная совместимость" (не всё можно перекомпилировать и пересобрать по разным причинам - или нет исходных текстов, или просто не позволяют ресурсы). Методы интерфейсов, определённые по умолчанию (default methods) - один из вариантов ответа на этот вопрос в Java 8. Default методы интерфейсов теперь содержат реализации. При этом соблюдается следующая логика:
- очевидно, что раз реализация default метода интерфейса существует до момента "овеществления" объекта, реализующего интерфейс, функциональность default-методов ограничена доступом к объектам "внешнего мира" - мы не можем оперировать несуществующим;
- все default-методы интерфейса по умолчанию являются публично доступными (public);
- при расширении интерфейса возможны три варианта - не обращать внимание на default-методы вообще (и их реализации будут использованы "как есть"), объявить не-default абстрактный метод с той же сигнатурой, что у default-метода из расширяемого интерфейса (в этом случае в новом расширенном интерфейсе метод станет абстрактным), явно переопределить (override) метод вместе с его реализацией;
- только если класс, реализующий интерфейс, реализует и все методы интерфейса, возможна его компиляция и последующее "овеществление" с использованием его собственных реализаций методов (включая default-методы), в противном случае Java-компилятор пытается отыскать default-реализации нереализованных методов в интерфейсе (интерфейсах), а в случае возникновения "бриллиантовой проблемы" (о ней - чуть позже два слова буквально), формируется ошибка компиляции;
- default-методы не нарушают бинарной совместимости кода, реализующего интерфейсы, то есть, их можно добавлять к интерфейсам, расширяя их для новых разработок, при этом старые библиотеки остаются полностью работоспособными (что подтверждается работоспособностью всех Java-приложений дремучих времён в Java 8, где уже default-методов интерфейсов море).
Упомянутую "бриллиантовую проблему" знают многие программисты, имеющие дело с языками, допускающими множественное наследование - если есть абстрактный класс A с одним единственным абстрактным методом M, этот класс наследуют и по-разному реализуют метод М два класса B и С, и есть четвёртый класс - D, наследующий классы B и C и не переопределяющий реализацию метода M, то какая из конкретных реализаций M должна использоваться овеществлениями класса D - B.M или C.M? Ответа на этот вопрос нет, это грубейшая семантическая ошибка на уровне проектирования, потому и "бриллиантовую проблему" жёстко называют "deadly diamond of death".
Кроме default-методов, обновлённые интерфейсы Java 8 позволяют описывать реализации статических (static) методов, являющихся общими для всего класса, а не для овеществлений отдельных объектов класса. Это, можно сказать, тактическое решение, упрощающее де-факто стандартную реализацию паттерна "фабрика объектов", который требовал в общем случае отдельного утилитарного класса со статическими методами генерации объектов. Появление статических методов в интерфейсах позволяет во многих случаях избежать потребности в таком дополнительном классе. Разработчики языка сочли это весомым аргументом.
В следующей записи будет тоже про интерфейсы, но уже настолько важное, что требует отдельного времени и места.
В целом впечатления от Java 8 более чем положительные. Конечно, ожидалось нечто большее (в первую очередь модульность), но, понимая сложность платформы и её критическую значимость для IT, с желаниями больших изменений можно повременить, куда важнее стабильная работа и сохранение всего, что сделано в мире Java за долгие годы существования платформы.
В качестве приятного бонуса - Java 8 при исполнении больших пользовательских приложений (из проверенных мной Netbeans 8, Eclipse, PyCharm и Intellij Idea) в Linux стала существенно "быстрее" и "легковеснее". Это очень заметно и радует.
На сегодня у меня всё.
Откланивась
Ready, set, buy! Посібник для початківців - як придбати Copilot для Microsoft 365
+1111 голосов |
все default-методы интерфейса по умолчанию являются публично доступными (public);
В С# да и в других языках ВСЕ методы интерфейса являются публично доступными (public). У Java разве не так? Прокомментируйте пожалуйста.
прокомментирую :)
интерфейс, как контракт, независимо от языка вообще, предназначен для объявления соблюдения требуемой внешней функциональности без ограничений или навязываний реализации.
посему интерфейсы всегда public - в этом их смысл.
я указал это явно просто потому, что default-методы - нечто новое и в оригинальной документации тоже явно указано, что они по умолчанию public. надо было разве что добавить - "и не надо явно писать им public", вопросов бы не было.
1) "они по умолчанию public". Означает ли это что они могут быть переопределены с меньшей видимостью(например, на private)?
2) У вас не написано но следуя логике default-методы могут быть только статическими. Я не прав? Можно пример?
Спасибо!
не означает. "public по умолчанию" означает только что явно не надо указывать модификатор public
у меня чётко написано - есть default-методы и есть static-методы. это разные методы, и это написано явно.
2) приведите пример default-метода. Без кода как-то не получается представить.
Спасибо!
http://docs.oracle.com/javase/tutorial/java/IandI/defaultmethods.html
Извините, что вмешиваюсь в вашу содержательную беседу :)
0) Большое спасибо!
1) У java-интерфейсов могут быть еще статические методы. Прикольно ;)
2) Вопрос. У интерфейса указывается область видимости (public ). Зачем? Может ли быть другая (например: private)?
Пишите кто знает. Спасибо!