Выпуск Java SE 14

После шести месяцев разработки компания Oracle выпустила платформу Java SE 14 (Java Platform, Standard Edition 14), в качестве эталонной реализации которой используется открытый проект OpenJDK. В Java SE 14 сохранена обратная совместимость с прошлыми выпусками платформы Java, все ранее написанные Java-проекты без изменений будут работоспособны при запуске под управлением новой версии. Готовые для установки сборки Java SE 14 (JDK, JRE и Server JRE) подготовлены для Linux (x86_64), Solaris, Windows и macOS. Разработанная в рамках проекта OpenJDK эталонная реализация Java 14 полностью открыта под лицензией GPLv2 с исключениями GNU ClassPath, разрешающими динамическое связывание с коммерческими продуктами.

Java SE 14 отнесён к категории выпусков с обычным сроком поддержки, обновления для которого будут выпускаться до следующего релиза. В качестве ветки с длительным сроком поддержки (LTS) следует использовать Java SE 11, обновления для которого будут выпускаться до 2026 года. Прошлая LTS-ветка Java 8 будет поддерживаться до декабря 2020 года. Следующий LTS-релиз намечен на сентябрь 2021 года. Напомним, что начиная с выпуска Java 10 проект перешёл на новый процесс разработки, подразумевающий более короткий цикл формирования новых релизов. Новая функциональность теперь развивается в одной постоянно обновляемой master-ветке, в которую включаются уже готовые изменения и от которой раз в шесть месяцев ответвляются ветки для стабилизации новых выпусков.

Из новшеств Java 13 можно отметить:

  • Добавлена экспериментальная поддержка сопоставления c образцом в операторе «instanceof», которая позволяет сразу определить локальную переменную для обращения к проверенному значению. Например, можно сразу писать «if (obj instanceof String s && s.length() > 5) {.. s.contains(..) ..}» без явного определения «String s = (String) obj».
    Было:
         if (obj instanceof Group) {       Group group = (Group) obj;       var entries = group.getEntries();     }  

    Теперь можно обойтись без определения «Group group = (Group) obj»:

         if (obj instanceof Group group) {       var entries = group.getEntries();     }  
  • Добавлена экспериментальная поддержка нового ключевого слова «record«, предоставляющего компактную форму для определения классов, позволяющую обойтись без явного определения различных низкоуровневых методов, таких как equals(), hashCode() и toString(), в случаях, когда данные сохраняются только в полях, поведение работы с которыми не меняется. Когда в классе используются типовые реализации методов equals(), hashCode() и toString(), в нём можно обойтись без их явного определения:
         public record BankTransaction(LocalDate date,                                double amount,                                String description) {}  

    Данное объявление приведёт к автоматическому добавлению реализаций методов equals(), hashCode() и toString() в дополнение к конструктору и методам, контролирующим изменение данных (getter).

  • Стандартизирована и включена по умолчанию поддержка новой формы выражений «switch», не требующей указания оператора «break», позволяющей объединять повторяющиеся метки и допускающей использование не только в форме оператора, но и как выражения.
         var log = switch (event) {         case PLAY -› "User has triggered the play button";         case STOP, PAUSE -› "User needs a break";         default -> {             String message = event.toString();             LocalDateTime now = LocalDateTime.now();             yield "Unknown event " + message +                 " logged on " + now;         }     };  
  • Расширена экспериментальная поддержка текстовых блоков — новой формы строковых литералов, позволяющих включать в исходный код многострочные текстовые данные без применения в них экранирования символов и сохраняя исходное форматирования текста в блоке. Обрамление блока осуществляется тремя двойными кавычками. В Java 14 в текстовых блоках реализована поддержка escape-последовательности «s» для определения одного пробела и «» для объединения со следующей строкой (игнорирования перевода строки, когда нужно вывести очень длинную строку). Например, вместо кода
         String html = "‹HTML›" +     "nt" + "‹BODY›" +     "ntt" + "‹H1›"Java 14 is here!"‹/H1›" +     "nt" + "‹/BODY›" +     "n" + "‹/HTML›";  

    можно указать:

         String html = """     ‹HTML›       ‹BODY›         ‹H1›"Java 14   is here!"‹/H1›       ‹/BODY›     ‹/HTML›""";  
  • Расширена информативность диагностики при возникновении исключений NullPointerException. Если раньше сообщение об ошибке лишь ссылалось на номер строки, то теперь в нём детализируется какой из методов вызвал исключение. Расширенная диагностика пока включается только при запуске с флагом «-XX:+ShowCodeDetailsInExceptionMessages». Например, при указании данного флага исключение в строке
         var name = user.getLocation().getCity().getName(); 

    приведёт к выводу сообщения

         Exception in thread "main" java.lang.NullPointerException: Cannot invoke "Location.getCity()"      because the return value of  "User.getLocation()" is null     at NullPointerExample.main(NullPointerExample.java:5):5) 

    которое позволяет понять, что метод Location.getCity() не был вызван, а User.getLocation() вернул значение null.

  • Реализован предварительный вариант утилиты jpackage, позволяющей создавать пакеты для самодостаточных (self-contained) Java-приложений. Утилита базируется на javapackager из JavaFX и позволяет формировать пакеты в форматах, родных для различных платформ (msi и exe для Windows, pkg и dmg для macOS, deb и rpm для Linux). Пакеты включают все необходимые зависимости.
  • В сборщик мусора G1 добавлен новый механизм распределения памяти, учитывающий специфику работу на крупных системах, использующзих архитектуру NUMA. Новый распределитель памяти включается при помощи флага «+XX:+UseNUMA» и позволяет существенно поднять производительность на NUMA-системах.
  • Добавлен API для отслеживания на лету событий JFR (JDK Flight Recorder), например для организации непрерывного мониторинга.
  • Добавлен модуль jdk.nio.mapmode, предлагающий новые режимы (READ_ONLY_SYNC, WRITE_ONLY_SYNC) для создания отображаемых байтовых буферов (MappedByteBuffer), ссылающихся на энергонезависимую память (NVM).
  • Реализован предварительный вариант API Foreign-Memory Access, позволяющий Java-приложениям безопасно и эффективно получить доступ к областям памяти, вне кучи Java, манипулируя новыми абстракциями MemorySegment, MemoryAddress и MemoryLayout.
  • Объявлены устаревшими порты для ОС Solaris и процессоров SPARC (Solaris/SPARC, Solaris/x64 и Linux/SPARC) c намерением удалить данные порты в будущем. Перевод укахзанных портов в разряд устаревших позволит сообществу ускорить разработку новых возможностей OpenJDK, не тратя время на поддержание особенностей, специфичных для Solaris и SPARC.
  • Удалён сборщик мусора CMS (Concurrent Mark Sweep), который два года назад был отмечен устаревшим и остался без сопроводжения (на смену CMS давно пришёл сборщик мусора G1). Кроме того, объявлена устаревшей применеие комбинации алгоритмов сборки мусора ParallelScavenge и SerialOld (запуск с опциями «-XX:+UseParallelGC -XX:-UseParallelOldGC»).
  • Обеспечена экспериментальная поддержка сборщика мусора ZGC (Z Garbage Collector) на платформах macOS и Windows (ранее поддерживался только в Linux). ZGC работает в пассивном режиме, насколько это возможно минимизирует задержки из-за сборки мусора (время остановки при использовании ZGC не превышает 10 мс.) и может работать как с небольшими, так и с огромными кучами, размером от нескольких сотен мегабайт до многих терабайт.
  • Удалены инструментарий и API для сжатия JAR-файлов с использованием алгортима Pack200.

Источник: http://www.opennet.ru/opennews/art.shtml?num=52559