9 мифов о Java

9 мифов о Java


Дата публикации 03.04.2023



С момента первого выпуска Java в 1995 году многое изменилось как в программном, так и в аппаратном обеспечении. Мощные процессоры и более дешевая память позволяют нашим приложениям работать быстрее и обрабатывать большее количество информации. Язык программирования Java все эти годы тоже не стоял на месте и активно развивался, однако успел обрасти мифами. В этой статье мы рассмотрим ряд ложных и устаревших представлений о Java.

Перевод. Оригинал статьи: https://foojay.io/today/9-outdated-ideas-about-java/

Миф 1: Java старая и не развивается.

Бытует мнение что Java это устаревший язык программирования, хотя PHP такой же старый, а тот же Python ещё на четыре года старше.

Что касается развития языка, то у Java до 9-й версии не было установленного графика выпуска. Новая версия выпускалась, когда реализовывался предопределенный список новых функций. Но с 2018 года у Java появился шестимесячный цикл релизов с фиксированными датами, и каждая новая версия содержит функции, которые полностью завершены и протестированы сообществом. Также в релизе присутствуют и экспериментальные функции, которые все еще находятся в разработке, однако они доступны только в том случае, если приложение собрано и запущено с дополнительными флагами.

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

Вот очень краткий обзор ряда изменений в версиях OpenJDK, но имейте в виду, что это лишь малая часть новых функций и улучшений. Некоторые функции были впервые представлены как экспериментальные (превью) и доработаны только в более поздней версии:

Версия Изменения
OpenJDK 19 Виртуальные потоки (превью)
OpenJDK 18 Pattern Matching для switch (второй превью)
OpenJDK 17 Sealed типы
OpenJDK 16 Новый тип объявления классов - record, Pattern matching для instanceof
OpenJDK 15 Текстовые блоки
OpenJDK 14 Helpful NPE, стримминг из запущенного приложения в JFR, Java Packager (jpackage), Pattern matching
OpenJDK 13 Улучшенные версии превью-фич
OpenJDK 12 Первое превью текстовых блоков
OpenJDK 11 Упрощённый запуск программ из одного файла, Java Flight Recorder (JFR)
OpenJDK 10 Local Variable Type Inference (LVTI) - он же тип var
OpenJDK 9 Модульность, Java Dependency Analyser (jdeps), Java Shell (jshell)
OpenJDK 8

Лямбда-выражения и Stream API, default-методы в интерфейсах. Всё это очень сильно повлияло на стиль программирования на Java.

Факт: 6-месячный цикл выпуска привнес много изменений в OpenJDK.

 

Миф 2: Нужно скомпилировать код, прежде чем его можно будет запустить

Действительно, Java - это компилируемый язык программирования, и для выполнения программы лучший вариант это предварительно скомпилировать код в class-файл. Этот файл содержит байтовый код, который может выполняться виртуальной машиной Java (JVM) на любой платформе.

Но есть и другие способы выполнения Java-кода! 

В Java 9 появился jshell как часть Java Development Kit (JDK). Это интерфейс командной строки для выполнения кода Java, который можно использовать, например, для тестирования ваших кусков кода. Как описано в JEP 222, код все еще компилируется, но это происходит за кулисами.

% jshell
|  Welcome to JShell -- Version 18.0.1
|  For an introduction type: /help intro

jshell> String message = "Hello World";
message ==> "Hello World"

jshell> "Test: " + message
$2 ==> "Test: Hello World" 

jshell> 8*9
$3 ==> 72

А в Java 11 появился новый способ - выполнения однофайлового кода. Он позволяет запускать программу, состоящую из одного файла, точно так же, как запускаются скрипты PHP или bash. Например:

java HelloWorld.java

Кроме этого, существует такой инструмент, как JBang, который позволяет выполнять код, использующий зависимости, без необходимости его компилировать или использовать инструменты сборки (Maven или Gradle). И если на компьютере не установлена Java, то JBang поставит её за вас!

Факт: под капотом действительно Java-код должен быть скомпилирован, прежде чем его можно будет запустить. Но теперь доступны различные инструменты, которые позволяют «скрыть» этот процесс и упростить непосредственное выполнение Java-кода.

 

Миф 3: Java медленная

C 1999 года в Java появилась динамическая (Just-In-Time) компиляция.

Текущий Hotspot JIT компилятор или например улучшенный компилятор Falcon, разработанный компанией Azul, позволяют приложениям на Java работать наравне с приложениями на C++. Так же Java намного быстрее, чем большинство популярных скриптовых языков, таких как Python или JavaScript.

Однако есть нюанс - приложения на Java запускаются медленнее, чем приложения на C++, и требуют специальной подготовки, пока JIT компилятор не начнет действовать. Из-за данной особенности в начале 2000-х годов на персональных компьютерах запуск Java-приложений происходил заметно медленнее, приложений на C++, из-за чего создалось впечатление что Java работает медленно.

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

Факт: Java однозначно доминирует в серверной разработке, и, благодаря своей скорости, очень часто применяется для написания высоконагруженных приложений в крупных компаниях.

 

Миф 4: Java небезопасна

В конце 90-х и 2000-х простого HTML было явно недостаточно, поэтому были очень популярны браузерные плагины, которые позволяли запускать различные приложения. Наиболее известными в то время технологиями были Flash, ActiveX, Silverlight и Java-апплеты. Все эти технологии, основанные на плагинах, устарели и полностью запрещены в корпоративной среде, так как с развёртыванием и безопасностью у них очень плохо.

Среди этих технологий Flash был одним из самых уязвимых, и хотя Java-апплеты были лучше изолированы и безопаснее чем Flash - полностью проблема безопасности решена не была, что и способствовало распространению мифа о том, что Java небезопасна.

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

Многие дистрибьюторы выпускают улучшенные среды выполнения в течение нескольких часов или дней после публикации списка обнаруженных уязвимостей и угроз (CVE).

Факт: полностью безопасной системы не существует, но наличие рабочего процесса, который собирает, документирует и устраняет проблемы, гарантирует, что безопасность Java поддерживается на высоком уровне.

 

Миф 5: Сложно установить Java на свой компьютер, и не понятно что с лицензией

Поскольку OpenJDK - это проект с открытым исходным кодом, любой может создать свою реализацию JVM. Многие некоммерческие и коммерческие организации как раз взяли на себя эту роль.

Это привело к появлению длинного списка дистрибутивов, которые вы можете использовать на всех типах устройств, от высокопроизводительных серверов до одноплатных компьютеров, таких как Raspberry Pi. Выбирайте то, что вам больше подходит, и оно будет работать на вашем устройстве, поскольку все дистрибутивы основаны на одних и тех же ветках OpenJDK и (должны быть) протестированы на соответствие спецификациям. Некоторые компании могут предоставлять дополнительные инструменты, поддержку и лицензии.

Факт: большинство дистрибутивов OpenJDK имеют установщики для различных платформ, а такие инструменты, как SDKMAN, позволяют легко устанавливать и переключаться между версиями.

 

Миф 6: Для запуска Java-кода на ПК должна быть установлена среда выполнения Java

Традиционно среда выполнения Java (JRE) используется для выполнения программ на Java. Но, начиная с OpenJDK 11, имеется альтернатива - связать требуемую JRE с приложением для удобства развертывания и максимальной совместимости.

jlink (JEP 282) - это инструмент, который позволяет собирать модули и их зависимости в пользовательский образ Java Runtime. Можно сказать, что он создает минимально необходимую среду выполнения Java (JRE), специально поддерживающую ваше приложение.

Начиная с OpenJDK 14, был добавлен jpackage (JEP 343) для создания собственного исполняемого файла на основе вывода jlink. Так jpackage создает один исполняемый файл, который автоматически распаковывается без участия пользователя.

Есть и другие упаковщики, например, GluonFX Plugin for Maven может создавать приложения для Windows, macOS, Linux, Android и iOS.

Факт: установка среды выполнения Java на вашем компьютере — это самый простой способ запуска приложений Java. Но доступны и другие инструменты для создания исполняемых файлов, в которые включена среда выполнения JRE.

 

Миф 7: Приложение приостанавливается во время очистки памяти

В некоторых ситуациях это именно то что нужно, особенно когда правильность результата важнее скорости выполнения, например для длительных пакетных операций. И в таком случае лучше всего подойдет так называемый сборщик мусора Stop-The-World.

Однако за прошедшие годы было реализовано множество других сборщиков мусора, и некоторые из них работают изолированно от потоков вашего приложения (параллельные сборщики мусора) и почти не влияют на выполнение кода, либо влияют минимально (минимальное время остановки). Из стандартных это Garbage First и Z Garbage Collector, а до это ещё был Concurrent Mark Sweep, но в данный момент он объявлен устаревшим. Так же имеются и сторонние реализации, например C4 GC (Continuously Concurrent Compacting Collector) от Azul.

Факт: в некоторых ситуациях сборщик мусора Stop-The-World - это то что нужно, а для других случаев можно использовать параллельные сборщики мусора.

 

Миф 8: Java не поддерживает множественного наследования

Изначально в Java не поддерживалось множественное наследование чтобы избежать так называемой "проблемы алмаза" (diamond problem), она же - ромбовидное наследование. Однако, с появлением JDK 8 появилась возможность множественного наследования поведения с решением данной проблемы.

Давайте рассмотрим пример с двумя интерфейсами ExampleA и ExampleB, имеющими дефолтный метод doSomething(). Если некий класс ExampleC имплементирует интерфейсы ExampleA и ExampleB, то вызов метода doSomething() приведет к двусмысленности, поскольку и ExampleA, и ExampleB предоставляют этот метод, и компилятор не знает какой из них использовать.

interface ExampleA {
    default void doSomething() {
        System.out.println("Output of A");
    }
}

interface ExampleB {
    default void doSomething() {
        System.out.println("Output of B");
    }
}

public class ExampleC implements ExampleA, ExampleB {

    @Override
    public void doSomething() {
        System.out.println("Output of C");
    }

    public static void main(String args[]){
        ExampleC example = new ExampleC();
        example.doSomething();
    }

}

Приведенный выше код без переопределённого метода doSomething() в ExampleC сгенерирует эту ошибку:

class ExampleC inherits unrelated defaults for doSomething() from types ExampleA and ExampleB

Но достаточно переопределить doSomething() в ExampleC и компилятор сразу поймёт что от него хотят:

Output of C

Факт: начиная с JDK 8 доступно множественное наследование поведения.

 

Миф 9: Интерфейсы не могут содержать методы с реализацией

Статические методы и default-методы сняли это ограничение с Java, теперь можно легко поместить реализацию в интерфейс.

Как вы можете видеть в приведенном выше примере кода, оба интерфейса ExampleA и ExampleB содержат метод, выполняющий код.

Факт: это уже не так, и интерфейсы могут содержать методы с реализацией.

 

Заключение

С момента перехода на шестимесячный цикл релизов в 2018 году язык и инструменты Java претерпели множество изменений Одни фичи находятся «под капотом» и служат для повышения производительности и улучшения использования памяти, в то время как другие ориентированы на упрощение написания и поддержку кода. Так же не забываем и про prewiew-фичи!

Список фич можно посмотреть тут. Особенно любопытен раздел "Draft and submitted JEPs".