JavaRush /Java Blog /Random-TL /Java 14: ano ang bago?

Java 14: ano ang bago?

Nai-publish sa grupo
Ang mga problema ng mundo ay mga problema ng mundo, at ang bagong Java ay nasa iskedyul. Ibig sabihin, eksaktong isang beses bawat anim na buwan. Ang release na bersyon ng Java 14 ay inilabas noong Marso 17, at nagpakilala ng ilang kawili-wiling mga inobasyon sa wikang naglalayon sa mga developer. Kabilang sa mga ito ang pang-eksperimentong suporta para sa recordJava 14: что нового? - 1 na keyword , suporta para sa pagtutugma ng pattern sa operator na " instanceof ", mas madaling gamitin na NullPointerExceptions , pinalawak na "pag-preview" ng mga text block , isang na-update na default na switch , at marami pa. Paalalahanan ka namin na ang lahat ng inobasyon sa Java ay nagsisimula sa mga panukalang extension ( JEP, Java Enhancement Proposals ). Ang mga developer ay nagmumungkahi ng mga pagbabago, ang mga ito ay sinusuri ng "opisyal" na mga magulang ng Java, at pagkatapos ay ang ilan sa mga pagbabagong iyon ay tinatanggap, pagkatapos ay naging bahagi sila ng JDK. At ngayon - tungkol sa lahat ng bagay sa pagkakasunud-sunod.

JEP 359: Mga Tala

Ang mga tala, na kilala rin bilang Mga Tala, ay magagamit para sa JDK 14 sa preview mode, at ito ay isang bagay na ganap na bago para sa Java. Sa katunayan, mayroon kaming bago sa amin ng isang bagong uri na binuo sa panahon ng proyekto ng Valhalla . Ang mga tala ay katulad ng mga enumerasyon at nagbibigay-daan sa iyong pasimplehin ang iyong code. Sa pangkalahatan, pinapalitan nila ang mga klase na may estado ngunit walang pag-uugali. Sa madaling salita, may mga field, walang mga pamamaraan. Sa kaso ng mga klase, minsan kailangan nating sumulat ng maraming paulit-ulit na code na hindi palaging kinakailangan: Mga konstruktor, accessor, equals(), hashCode(), toString(), atbp. Upang maiwasan ang paulit-ulit na code na ito, Java plans gamitin ang record. Narito ang klasikong bersyon:
final class Triangle {
 	public final int x;
public final int y;
public final int z;

    public Triangle(int x, int y, int z) {
         this.x = x;
         this.y = y;
    this.z = z;
    }
    // equals, hashCode, toString
Lumipat tayo sa Java 14 at gamitin ang record:
public record Triangle(int x, int y, int z){}
Iyon lang. Mangyaring tandaan na ang mga pag-record ay kasalukuyang umiiral sa preview form, kaya upang subukan ang mga ito sa pagsasanay kailangan mong i-download ang jdk14 at ilagay ang command:
javac —enable-preview —release 14 Triangle.java
Ang mga rekord ay mga klase, kahit na may mga limitasyon. Hindi sila maaaring mag-extend ng ibang mga klase o magdeklara ng mga field (maliban sa pribadong final na tumutugma sa mga bahagi ng deklarasyon ng estado). Ang mga talaan ay ganap na pinal at hindi maaaring abstract. Naiiba ang mga tala sa mga regular na klase dahil hindi nila maihihiwalay ang kanilang API sa representasyon nito. Ngunit ang pagkawala ng kalayaan ay binabayaran ng mas mataas na katumpakan. Ang mga bahagi ng record ay ganap ding pinal.

JEP 305: Pattern Matching for instanceof (Preview)

Ang tampok na Pagtutugma ng Pattern , na ipinakilala sa Java 14 sa preview, ay idinisenyo upang pagsamahin ang pagsuri sa uri ng isang bagay at ang conversion nito sa instanceof operator. Sa madaling salita, bago ang Java 14 ay mayroon, halimbawa, ang sumusunod na code:
Object object = Violin;

if (object instanceof Instrument) {
    Instrument instrument = (Instrument) object;
    System.out.println(instrument.getMaster());
}
Tulad ng nakikita mo, dapat nating ihagis ang bagay sa klase na ang mga pamamaraan ay gusto nating gamitin. Ngayon ang Java 14 at ang konektadong tampok na Pagtutugma ng Pattern ay nagpapahintulot sa iyo na bawasan ang code sa sumusunod:
Object object = Violin;

if (object instanceof Instrument instrument){
    System.out.println(instrument.getMaster());
}

JEP 343: Packaging Tool (Incubator)

В JDK 8 был инструмент javapackager, предназначенный для JavaFX. Однако после отделения JavaFX от Java вместе с выпуском JDK 11, популярный javapackager оказался более не доступным. Javapackager представлял собой инструмент упаковки. Он позволял упаковывать applications Java таким образом, чтобы их можно было установить, How и все другие “нормальные” программы. Например, создавать exe-файлы для пользователей Windows и запускать Java-приложение по-человечески — двойным щелчком мыши. Разумеется, такого инструмента очень не хватает, поэтому в JEP 343 предложor новый инструмент jpackage, который собирает Java-приложение в пакет для конкретной платформы, содержащий все необходимые зависимости. Поддерживаемые форматы пакетов для конкретной платформы:
  • Linux: deb и rpm
  • macOS: pkg и dmg
  • Windows: MSI и EXE

JEP 345: NUMA-Aware Memory Allocation для G1

JEP 345 служит исключительно для реализации поддержки NUMA (Non-uniform memory access). Это архитектуры с неоднородным доступом к памяти, способом настройки кластера микропроцессора в многопроцессорную систему, при которой память может быть распределена локально: каждое ядро процессора получает небольшой объем локальной памяти, при этом другие ядра имеют к ней доступ. JEP 345 планирует оснастить сборщик мусора G1 возможностью рационально использовать такие архитектуры. Помимо всего прочего, такой подход помогает повысить производительность на очень мощных машинах.

JEP 349: JFR Event Streaming

Java Flight Recorder (JFR) теперь является частью OpenJDK и поэтому находится в свободном доступе. В JDK 14 добавлен API для отслеживания на лету событий JFR (JDK Flight Recorder), в частности — для организации непрерывного мониторинга активных и неактивных приложений. Записываются те же события, что и для не-потокового варианта, с накладными расходами менее 1%. Таким образом, потоковая передача событий будет осуществляться одновременно с вариантом без потоковой передачи. Однако JEP 349 не должен разрешать синхронные callback’и для соответствующего потребителя. Даже данные из записей, хранящихся в промежуточной памяти, не должны быть доступны. Технически пакет jdk.jfr.consumer в модуле jdk.jfr будет расширен функциональностью для асинхронного доступа к событиям.

JEP 352: Non-Volatile Mapped Byte Buffers

Как известно, Java NIO (New IO) File API существует с JDK 1.4,, а затем было представлено новое усовершенствование под названием Path. Path — это интерфейс, который заменяет класс java.io.File How представление file or каталога, когда мы работаем в Java NIO. JEP 352 расширяет MappedByteBuffer для загрузки части файловых данных в энергонезависимую память (NVM). Эта память компьютера, данные в которой не будут потеряны даже в случае отключения питания (её часто называют постоянной памятью) используется для постоянного хранения данных. Это предложение по улучшению Java предоставляет новый модуль и класс для JDK API: модуль jdk.nio.mapmode, предлагает новые режимы (READ_ONLY_SYNC, WRITE_ONLY_SYNC) для создания отображаемых byteовых буферов (MappedByteBuffer), ссылающихся на NVM.

JEP 358: Helpful NullPointerExceptions

Теперь исключения NullPointerExceptions будут более дружественными к программисту. В том смысле, что описание исключения будет гораздо более информативным, чем раньше. А всё потому, что JVM научor более точно анализировать инструкции byte-codeа программы, и она может указать, Howая именно переменная приводит к нулевому значению. Допустим, у нас есть code:
a.getMessage().getUserInfo().getName()
В любой из последних Java мы получим обычный лог ошибки, который не отвечает на вопрос, кто именно null:
Exception in thread "main" java.lang.NullPointerException
	at Main.main(Main.java:12)
А вот что выдаст Java 14, если вы решитесь испробовать данную превью-фичу:
Exception in thread "main" java.lang.NullPointerException: Cannot invoke "UserInfo().getName()" because the return value of "Message().getUserInfo()" is null
	at Main.main(Main.java:12)
Такая цепочка гораздо более понятна, и позволяет гораздо быстрее взяться за устранение ошибки.

JEP 361: Switch Expressions (Standard)

Обновлённый оператор Switch был доступен ещё в предыдущих Java 12 и 13, но только How превью-функция, то есть, она не была включена по умолчанию. Теперь в JDK 14 всё работает “из коробки”. Java 14 представляет новую упрощенную форму блока switch с метками case L -> .... Новая форма в некоторых случаях упрощает code. Вот пара примеров. Предположим, что у нас есть enum, который описывает дни недели. Мы можем написать классический code (до Java 14):
switch (day) {
    case MONDAY:
    case FRIDAY:
    case SUNDAY:
        System.out.println(6);
        break;
    case TUESDAY:
        System.out.println(7);
        break;
    case THURSDAY:
    case SATURDAY:
        System.out.println(8);
        break;
    case WEDNESDAY:
        System.out.println(9);
        break;
}
А вот — вариант с использованием Java 14:
switch (day) {
    case MONDAY, FRIDAY, SUNDAY -> System.out.println(6);
    case TUESDAY                -> System.out.println(7);
    case THURSDAY, SATURDAY     -> System.out.println(8);
    case WEDNESDAY              -> System.out.println(9);
}
Также можно писать многострочные блоки и возвращать meaning с новым ключевым словом yield:
int result = switch (s) {
    case "Working from Home" -> 1;
    case "Working from Office" -> 2;
    default    -> {
        System.out.println("Neither Home nor Office… Cafe? Car? Park?...");
        yield 0;
    }
};
Есть ещё несколько важных вещей, которые нужно иметь в виду при использовании новых switch. В частности, нужно помнить, что варианты должны быть исчерпывающими. То есть для всех возможных значений должна быть соответствующая switch-метка. Поскольку yield теперь является ключевым словом, класс с именем yield — возможен в Java 14. А вообще, если хотите научиться использовать обновлённые “свичи”, переходите на JEP 361, и изучайте. Там много интересной информации.

JEP 362: Deprecate the Solaris and SPARC Ports

Вряд ли многие наши читатели помнят об операционной системе Solaris. Эта операционка на базе UNIX, созданная родителями Java — компанией Sun Microsystems, использовалась преимущественно для serverов на SPARC-архитектуре… Слишком много незнакомых слов на квадратный сантиметр? Ничего страшного: JEP 362 прекращает поддержку платформ Solaris/SPARC, Solaris/x64 и Linux/SPARC. То есть их порты теперь Deprecated, а в будущем они, скорее всего, будут удалены из OpenJDK. Однако старые версии Java (до JDK 14) относительно портов Solaris/SPARC, Solaris/x64 и Linux/SPARC должны работать без изменений. Если вы — любитель истории и интересуетесь технологиями не такого уж далёкого прошлого — гоу в “Википедию” читать об архитектуре SPARС.

JEP 363: Remove the Concurrent Mark Sweep (CMS) Garbage Collector

Сборщик мусора CMS (Concurrent Mark Sweep) направлен на удаление, поскольку ещё два года назад был помечен How устаревший и остался без сопровождения. Однако пользователи старых версий Java, использующие CMS GC, могут выдохнуть — цель этого JEP’а не в том, чтобы удалить сборщик из более ранних выпусков JDK. Кроме того, объявлено устаревшим применение комбинации алгоритмов сборки мусора ParallelScavenge и SerialOld (запуск с опциями "-XX:+UseParallelGC -XX:-UseParallelOldGC").

JEP 364: ZGC on macOS и JEP 365: ZGC on Windows

Есть такой интересный сборщик мусора по имени Z Garbage Collector (ZGC). Он работает в пассивном режиме, и старается максимально сократить задержки из-за сборки мусора: время остановки при использовании ZGC не превышает 10 мс. Он может работать с маленькими кучами (heap) и с гигантскими (теми, что занимают много тераbyte). JEP 364 и JEP 365 — практически близнецы. JEP 364 переносит Z Garbage Collector на MacOS. Часть JEP также описывает функциональность сборщика для освобождения неиспользуемой памяти устройства, How указано в JEP 351, это происходит с Java 13. Реализация ZGC в macOS состоит из двух частей:
  • Поддержка multi-mapping memory на macOS
  • Поддержка в ZGC непрерывного резервирования памяти
JEP 365 обеспечивает поддержку ZGC уже на Windows, и тоже в экспериментальном режиме. Она заключается в следующем:
  • Поддержка multi-mapping memory
  • Поддержка маппинга памяти на основе file подкачки в зарезервированное addressное пространство
  • Поддержка маппинга и анмаппинга произвольных частей кучи
  • Поддержка коммита и анкоммита произвольных частей кучи

JEP 366: Deprecate the ParallelScavenge + SerialOld GC Combination

Этот JEP объявляет устаревшим использование комбинации алгоритмов для сборки мусора Parallel Scavenge и Serial Old. Такую комбинацию нужно было включать вручную с помощью параметров командной строки -XX: + UseParallelGC -XX: -UseParallelOldGC. Authorы считают, что комбинация очень специфична, но при этом требует существенных усorй по обслуживанию. Так что теперь опция -XX: UseParallelOldGC устарела, и в случае использования будет появляться предупреждение.

JEP 367: Remove the Pack200 Tools and API

Pack200 — это формат архива, оптимизированный для хранения скомпorрованных файлов Java-классов. Этот инструмент был помечен словом deprecated (устаревший) ещё со времён Java 11. Теперь инструменты pack200, unpack200 а также Pack200 API официально заявлены на удаление из java.util.jar package. Данная технология была введена ещё в Java 5, How средство борьбы с весьма ограниченной пропускной способностью (модемы, страшно сказать и вспомнить, 56k) и недостаточным пространством для хранения на жестких дисках. Какое-то время назад в Java 9 были представлены новые схемы сжатия. Разработчикам рекомендуется использовать jlink.

JEP 368: Text Blocks (Second Preview)

Текстовые блоки впервые появorсь в Java 13. Это многострочные строковые литералы, которые предотвращают необходимость в большинстве escape-последовательностей, автоматически форматируют строку, а также позволяют разработчику форматировать строку при необходимости. Теперь эта полезная функция доступна в Java 14 (вторая, предварительная version). Главная задача текстовых блоков — улучшить работу с запутанными многострочными литералами. Это существенно упрощает чтение и написание SQL-requestов, HTML- и XML-codeа, JSON. Пример HTML без текстовых блоков:
String html = "<html>\n" +
              "    <body>\n" +
              "        <p>Hello, JavaRush Student</p>\n" +
              "    </body>\n" +
              "</html>\n";
Как представить то же самое с текстовыми блоками:
String html = """
              <html>
                  <body>
                      <p>Hello, JavaRush Student</p>
                  </body>
              </html>
              """;
Открывающий разделитель — это последовательность из трех символов двойных кавычек ("" "), за которыми следуют ноль or более пробелов, а затем — разделитель строки. Содержимое начинается с первого символа после разделителя строки открывающего разделителя. Закрывающий разделитель представляет собой последовательность из трех символов двойных кавычек. Содержимое заканчивается на последнем символе перед первой двойной кавычкой закрывающего разделителя. Содержимое может непосредственно вмещать символы двойных кавычек, в отличие от символов в строковом литерале. Использование \ в текстовом блоке разрешено, но не обязательно or не рекомендуется. Жирные разделители (" "") были выбраны таким образом, чтобы символы могли отображаться без экранирования, а также визуально отличать текстовый блок от строкового литерала. В начале 2019 года в JEP 355 предложor текстовые блоки в качестве продолжения JEP 326 (Raw String literals), однако их отозвали. Позднее в том же году, в JDK 13 представor функцию предварительного просмотра текстового блока, и теперь в Java 14 в неё добавor две новые escape-последовательности. Это символ новой строки (line-terminator), обозначенный \, и вторая — для пробела (single space), обозначается /s. Пример использования символов новой строки без текстовых блоков:
String literal = "This is major Tom to Ground Control " +
"I am stepping through the door... " +
"Wait… What???";
А теперь — с эскейп-последовательностью \<line-terminator>:
String text = """
                This is major Tom to Ground Control \
                I am stepping through the door... \
                WaitWhat???\
                """;
Эскейп-последовательность \s используется для учета завершающих пробелов, которые по умолчанию игнорируются компилятором. Он сохраняет все имеющиеся перед ним пробелы. Пример:
String text1 = """
               line1
               line2 \s
               line3
               """;

String text2 = "line1\nline2 \nline3\n";
text1 и text2 — идентичны.

JEP 370: Foreign-Memory Access API (Incubator)

Многие популярные библиотеки и программы Java имеют доступ к внешней памяти. Например, Ignite, MapDB, Memcached и Netty ByteBuf API. При этом они могут избежать затрат и непредсказуемости, связанных со сборкой мусора (особенно при обслуживании больших кэшей), совместно использовать память между несколькими процессами, а также сериализовать и десериализовать содержимое памяти путем сопоставления файлов в памяти (например, с помощью mmap). Однако Java API до сих пор не обзавелась подходящим решением для доступа ко внешней памяти. В JDK 14 можно подключить предварительный вариант API Foreign-Memory Access, который позволяет applicationsм Java безопасно и эффективно получить доступ к областям памяти, вне кучи виртуальной машины Java, с помощью новых абстракций MemorySegment, MemoryAddress и MemoryLayout.

Выводы

Ну How вам? По сравнению с Java 13, новая Java 14 предлагает гораздо больше важных улучшений в самых разных областях. Скорее всего, наиболее важными для разработчиков окажутся обновлённые switch, расширенные исключения NullPointerExceptions и records. Или нет?.. Не забудьте опробовать новые фичи Java 14, это очень полезно даже для новичков. Удачи в обучении!
Mga komento
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION