Java 9: The Good, The Bad, and Private Interface Methods

The following text is a partial translation of the original English article, performed by ChatGPT (gpt-3.5-turbo) and this Jekyll plugin:

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

Первым трендом является явное улучшение платформы, которая компилирует Java, упаковывает JAR-файлы и выполняет байт-код. Она определенно становится лучше с каждым новым релизом Java. Вот список улучшений, которые внес Java 9, и они, без сомнения, очень полезны:

  • JEP 222: jshell

  • JEP 238: Multi-release JARs” translates to Russian as follows: “JEP 238: JAR-файлы с поддержкой нескольких версий”

  • JEP 282: jlink” -> “JEP 282: jlink

  • JEP 158: Unified logging” - “JEP 158: Унифицированное ведение журнала”

Платформа очевидно становится более зрелой. Это хорошая тенденция.

Вторая тенденция, которую я наблюдаю с Java 6, показывает, что JDK, который в основном представляет собой набор классов и интерфейсов, разработанных и поддерживаемых Oracle, становится все больше с каждым новым выпуском. В Java 9 они добавили и расширили, среди прочего, следующее:

  • JEP 268: XML Catalogs (новый)”

  • JEP 262: TIFF image I/O (new) - JEP 262: ввод-вывод изображений TIFF (новый)

  • JEP 251: многоразрешительные изображения (новое)”

  • JEP 110: HTTP 2.0 клиент (новый)”

  • JEP 236: Parser для Nashorn (расширенный)”

Конечно, некоторые функции должны быть реализованы в самой JDK, такие как поддержка Unicode (JEP 267), платформо-специфичные функции рабочего стола (JEP 272), подсказки Spin-Wait (JEP 285), компактные строки (JEP 254) и API процесса (JEP 102). Их реализация зависит от базовой платформы и должна предоставляться вместе с JVM.

Но что HTTP 2.0 клиент делает в JDK вместе с JAX-RS, JPA, JAX-WS, JDBC и многими другими вещами, которые, по моему мнению, должны быть как можно дальше от Oracle? Они не зависят от платформы и могут быть лучше разработаны сообществом open source в виде независимых пакетов. Собирать их под одной общей зонтичной маркой - это ошибка, на мой взгляд.

Я считаю, что крупные корпорации только убивают рынок программного обеспечения, вместо того, чтобы сделать его лучше, из-за финансовых и политических мотивов, которым они подвергают его. Именно это происходит с JDK. Благодаря монополии Oracle у него отсутствует гибкость и динамичность в развитии. Другими словами, мы застряли с тем, что Oracle и его крупные партнеры считают правильным.

Таким образом, увеличение размеров JDK - это плохая тенденция. Я считаю, что Oracle только выиграет, сделав его меньше, делегируя все, что не является платформо-специфичным, open source сообществу, поддерживая программистов как-то и продвигая открытые и эффективные процессы стандартизации на рынке.

Java был разработан Джеймсом Гослингом в Sun Microsystems в 1995 году как объектно-ориентированный язык. Было много сомнений относительно этого утверждения об объектно-ориентированности, и я тоже не уверен, что Java более ООП, чем процедурный язык. Однако официально он является объектно-ориентированным.

Java унаследовала много процедурных особенностей от C/C++, начиная с первой версии, включая статические методы, NULL, наследование реализации и т.д. Это не был идеальный объектно-ориентированный язык, и не предполагалось, что он станет таким, насколько я понимаю. Главная идея заключалась в создании чего-то, что можно было бы написать один раз и запустить везде. Однако язык был важен также, а не только JVM. Он был простым и привлекательным.

Java 5 сделала серьезный шаг вперед в 2004 году и улучшила язык, добавив обобщения, цикл “for-each”, varargs и статический импорт. Однако были введены также аннотации и перечисления, которые помогли языку отклониться от объектной парадигмы к чему-то совершенно другому и процедурному.

Java 7 добавила try-with-resource в 2011 году, что было хорошим шагом в соответствии с ООП парадигмой.

Java 8 добавила лямбда-выражения в 2014 году, что было замечательной функцией, но совершенно не связано с ООП. Лямбда и API потоков превратили Java в смесь объектной, процедурной и функциональной парадигм. Методы по умолчанию также были добавлены в интерфейсы, что превратило типы в наборы кода. Типы в наборы кода! Это еще хуже, чем наследование реализации, на мой взгляд.

Теперь Java 9 сделала следующее “улучшение” для интерфейсов, позволяя им иметь приватные методы. Приватные статические методы в типах! Вы можете в это поверить? Какой будет следующий шаг? Атрибуты, в Java 10, наверное.

Также давайте посмотрим, что было сделано с некоторыми основными классами в JDK, чтобы понять, куда движется язык. Приведу только два примера.

Фабричные методы для коллекций (JEP 269). Вместо введения новых конструкторов и позволяя нам делать такое:

…in Java 9 they created more static factory methods and made us do this:

List<Integer> list = List.of(1, 2, 3);

“Меньше конструкторов, больше статических методов!” - такова философия тех, кто представил этот JEP. Нужно сказать, что это полностью противоречит самой сути объектно-ориентированного программирования. Объекты должны создаваться конструкторами, а не статическими методами, несмотря на то, что говорит Джошуа Блох. Статические методы делают момент использования оператора new невидимым для нас, и поэтому код становится гораздо менее поддерживаемым - мы просто не знаем, какой класс создается и какие реальные аргументы его конструктора.

Кстати, с помощью Cactoos вы можете сделать это правильным способом:

This is OOP.

Новые методы в InputStream. К уже перегруженному классу InputStream были добавлены три новых метода: transferTo(), readNBytes() и readAllBytes(). Теперь нам предлагается использовать следующий код, если мы хотим скопировать входной поток в выходной поток:

Это одна из самых типичных ошибок, которые совершают молодые программисты ООП: они делают свои интерфейсы большими. Просто потому, что им нужно больше функциональности. По-моему, принцип разделения интерфейса (Interface Segregation Principle) является частью знаменитого SOLID и существует уже много лет. Что с вами не так, Oracle? Какой будет следующий шаг? В Java 10 у нас также будут методы saveToFile() и printToConsole()? А как насчет emailToAFriend()?

Вот как вы бы сделали то же самое с помощью утилитного класса IOUtils из commons-io:

Это не идеально, но лучше. Самый объектно-ориентированный способ - использовать объекты, а не утилитарные классы и статические методы. Вот как это работает в Cactoos:

This is OOP.


На мой взгляд, Java становится некрасивой, и это тенденция. Значит ли это, что пора бросать? Нет! Неважно насколько ты некрасив, мы всегда будем любить тебя, Java!

Translated by ChatGPT gpt-3.5-turbo/42 on 2023-11-18 at 05:19

sixnines availability badge   GitHub stars