`

СПЕЦИАЛЬНЫЕ
ПАРТНЕРЫ
ПРОЕКТА

Архив номеров

Как изменилось финансирование ИТ-направления в вашей организации?

Best CIO

Определение наиболее профессиональных ИТ-управленцев, лидеров и экспертов в своих отраслях

Человек года

Кто внес наибольший вклад в развитие украинского ИТ-рынка.

Продукт года

Награды «Продукт года» еженедельника «Компьютерное обозрение» за наиболее выдающиеся ИТ-товары

 

Андрей Зубинский

Java 8 - что нового. Часть 1 - интерфейсы.

+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 стала существенно "быстрее" и "легковеснее". Это очень заметно и радует.

На сегодня у меня всё.

Откланивась

+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)?
Пишите кто знает. Спасибо!

 
 
IDC
Реклама

  •  Home  •  Рынок  •  ИТ-директор  •  CloudComputing  •  Hard  •  Soft  •  Сети  •  Безопасность  •  Наука  •  IoT