JavaRush /جاوا بلاگ /Random-UR /Вышла Java 11: новые фичи и возможности

Вышла Java 11: новые фичи и возможности

گروپ میں شائع ہوا۔
Это раньше новые версии Java появлялись редко и с задержками. Теперь же Oracle успешно держит заданный самой себе ритм «новая Java раз в полгода». Так что несколько дней назад, строго по графику, мы-таки получor Java SE 11 и реализацию JDK (Java Development Kit). Вышла Java 11: новые фичи и возможности  - 1Как всегда, новая version будет совместима со старыми, а поддержка Java 11 закончится не раньше декабря 2026 года.

Новые фичи Java SE 11 (видимые разработчикам)

Напомним, в Java изменения вносятся посредством внедрения JEP «JDK Enchancement Proposal». JEP — это предложение по улучшению OpenJDK, которое могут утвердить, отложить or отклонить. То есть, по сути, сборник JEP’ов — стратегия развития OpenJDK. В квадратных скобках перед новой «фичей» мы укажем номер соответсвующего JEP. [323] Local-Variable Syntax for Lambda Parameters — var-синтаксис для лямбда-параметров В Java 10 ввели ключевое слово var, которое позволяло не указывать явно тип локальной переменной. Это упрощало code. JEP 323 расширяет возможности использования такого синтаксиса по отношению к лямбда-выражениям. Простой пример:

list.stream ()
                 .map ((var s) -> s.toLowerCase ())
                 .collect (Collectors.toList ());
Как пишет Саймон Риттер, известный Java-евангелист, опытный Java-программист заметит, что использование var в данном случае может быть лишним, поскольку code выше можно заменить следующим:

list.stream ()
                  .map (s -> s.toLowerCase ())
                  .collect (Collectors.toList ());
Зачем, в таком случае, поддерживать var? Просто есть один особый случай — когда вы хотите добавить аннотацию к лямбда-параметру. Это невозможно сделать без участия Howого-либо типа, и чтобы не использовать явный тип, мы можем упростить всё с помощью var следующим образом:

list.stream ()
                 .map ((@ Notnull var s) -> s.toLowerCase ())
                 .collect (Collectors.toList ());
[330] Launch Single-File Source-Code Programs Усовершенствование Java-лаунчера для запуска программы в виде единого file с Java-исходниками Java частенько критикуют за многословный синтаксис и многоступенчатую «церемонию» запуска даже тривиального applications. Порой это отпугивает новичков. Для написания applications, которое просто печатает «Hello World!», нужно написать класс с общедоступным статическим void основным методом и использовать метод System.out.println. Сделав это, вы должны скомпorровать code с помощью javac. Наконец, после этого вы можете запустить приложение, которое выведет злополучное приветствие (разумеется, интегрированная среда разработки, How IDEA, так и встроенная в JavaRush, выполняет эту «магию запуска applications» самостоятельно — прим. ред.). Будем откровенны: в большинстве языков программирования реальный сценарий запуска программ выглядит гораздо проще. JEP 330 устраняет необходимость компиляции однофайлового applications, поэтому теперь, если вы пользуетесь командной строкой, просто введите

java HelloWorld.java
Лаунчер Java определит, что файл содержит исходный code Java и скомпиллирует code в файл класса перед его выполнением. После or до имени file с исходным codeом можно поместить параметры. Те, что помещены после имени, передаются в качестве параметров при выполнении applications. Те, что помещены до имени, передаются в качестве параметров лаунчеру Java после компиляции codeа. Параметры, относящиеся к компилятору (например, way to классам), также будут переданы javac для компиляции. Пример. Строка:

            java -classpath / home / foo / java Hello.java Bonjour
будет эквивалентна таким строкам:

            javac -classpath / home / foo / java Hello.java
            java -classpath / home / foo / java Hello Bonjour
[321] HTTP Client (Standard) — поддержка HTTP Client API стандартизирована В JDK 9 был представлен новый API для поддержки протокола HTTP Client (JEP 110). Поскольку в JDK 9 также внедрor платформу Java Platform Module System (JPMS), этот API был включен How инкубаторный модуль (это модули для предоставления разработчикам новых API, которые ещё не стали standard в Java SE, тогда How «действующие» API готовятся к удалению — разработчики могут испытать новые API и попробовать обеспечить обратную связь). После внесения необходимых изменений (этот API был обновлен в JDK 10), API может стать частью стандарта. Так вот, API HTTP Client теперь официально входит в Java SE 11. Это вводит новый модуль и пакет для JDK, java.net.http. Основные новые типы: HttpClient HttpRequest HttpResponse WebSocket Этот API можно использовать синхронно or асинхронно. В асинхронном режиме используются CompletionFutures и CompletionStages. [320] Remove The Java EE and CORBA Modules — удалены модули Java EE и COBRA Вместе с внедрением платформы Java Platform Module System (JPMS) в девятой версии Java, появилась возможность разделить монолитный файл rt.jar на несколько модулей. Кроме того, JPMS позволяет создать среду выполнения Java, которая включает только модули, необходимые для вашего applications, что существенно уменьшает её размер. С прозрачно определенными границами модулей стало гораздо проще удалить устаревшие части Java API — вот что делает JEP 320. Метамодуль java.se.ee включает в себя шесть модулей, которые не будут входить в стандарт Java SE 11 и не будут включены в JDK:
  • corba
  • transaction
  • activation
  • xml.bind
  • xml.ws
  • xml.ws.annotation
Эти модули объявor устаревшими (deprecated) ещё в JDK 9, и не были включены по умолчанию в компиляцию or выполнение. Это значит, если вы пробовали скомпorровать or запустить приложение, использующее API этих модулей на JDK 9 or JDK 10, у вас ничего не вышло. Если вы используете API этих модулей в своем codeе, вам нужно будет предоставить их в виде отдельного модуля or библиотеки.

Новые API

Большое количество новых API в JDK 11 появилось благодаря включению в стандарт языка модуля HTTP Client и Flight Recorder. С полным списком API можно ознакомиться в следующем полном и обстоятельном сравнении разных версий JDK, составленном Гуннаром Морлингом. А в этой заметке перечислим некоторые новые методы, которые не входят в модули java.net.http, jdk.jfr и java.security. java.lang.String Возможно, изменение в String — одно из самых важных в API JDK 11. Здесь есть несколько полезных новых методов.
  • boolean isBlank (): возвращает true, если строка пуста or содержит только пробелы, иначе false.

  • Stream lines(): возвращает поток строк, извлеченных из этой строки, разделенных терминаторами строк.

  • String repeat (int): возвращает строку, meaning которой представляет собой конкатенацию этой строки, повторяющуюся int раз.

  • String strip (): returns строку, из которой удалены все пробелы, которые находятся до первого символа, не являющегося пробелом, or после последнего.

  • String stripLeading (): returns строку, из которой удалены все пробелы, которые находятся до первого символа, не являющегося пробелом.

  • String stripTrainling (): returns строку, из которой удалены все пробелы, которые находятся после последнего символа, не являющегося пробелом.
What-то похожее на strip() уже делал метод trim (), только вот под пробелами эти методы понимают разные вещи. В случае trim() отсекаются только пробелы, а в strip() — ещё и спецсимволы, вроде табуляции. java.lang.StringBuffer java.lang.StringBuilder Оба этих класса содержат новый метод compareTo (), который принимает StringBuffer/StringBuilder и возвращает int. Метод лексического сравнения аналогичен новому методу compareTo() CharSequence. java.io.ByteArrayOutputStream
  • void writeBytes (byte []): записывает все byteы параметра в выходной поток java.io.FileReader
Здесь появилось два новых конструктора, которые позволяют указать Charset. java.io.FileWriter Четыре новых конструктора, которые позволяют указать Charset. java.io.InputStream
  • io.InputStream nullInputStream (): возвращает InputStream, который не считывает byteы. Как использовать этот метод? Можете считать его чем-то вроде /dev/null для выбрасывания ненужного вам вывода or для внедрения ввода, который всегда возвращает нуль byteов.
java.io.OutputStream
  • io.OutputStream nullOutputStream ()
java.io.Reader
  • io.Reader nullReader ()
java.io.Writer
  • io.Writer nullWriter ()
java.lang.Character
  • String toString (int): это перегруженная форма существующего метода, но instead of char используется int.
java.lang.CharSequence
  • int compare (CharSequence, CharSequence): лексикографически сравнивает два экземпляра CharSequence. returns отрицательное meaning, нуль or положительное meaning, если первая последовательность лексикографически меньше, равна or больше второй, соответственно.
java.lang.ref.Reference
    lang.Object clone (): евангелист Java Саймон Риттер признается, что этот метод его смущает. Класс Reference не реализует интерфейс Cloneable, и этот метод всегда будет генерировать исключение CloneNotSupportedException. Однако эксперт предполагает, что этот метод пригодится для чего-то в будущем.
java.lang.Runtime java.lang.System Здесь новых методов нет. Упомянем только, что метод runFinalizersOnExit () удален из обоих этих классов, что может вызвать проблемы с совместимостью. java.lang.Thread НиHowих дополнительных методов, упомянем только, что destroy () и stop (Throwable) были удалены. Однако stop (), который не принимает аргументов, все еще в наличии. Помните об этом, поскольку вполне возможны проблемы с совместимостью. java.nio.ByteBuffer java.nio.CharBuffer java.nio.DoubleBuffer java.nio.FloatBuffer java.nio.LongBuffer java.nio.ShortBuffer Во все эти классы разработчики языка добавor метод mismatch (), который находит и возвращает относительный индекс первого несоответствия между этим буфером и заданным буфером. java.nio.channels.SelectionKey
  • int interestOpsAnd (int)

  • int interestOpsOr (int)
java.nio.channels.Selector
  • int select (java.util.function.Consumer, long): выбирает и исполняет действие на клавишах, соответствующие каналы которых готовы для операций ввода-вывода. Параметр long — это тайм-аут.

  • int select (java.util.function.Consumer): работает, How метод выше, только без таймаута.

  • int selectNow (java.util.function.Consumer): работает, How метод выше, только он non-blocking.

java.nio.file.Files
  • String readString (Path): считывает весь контент из file в строку, деcodeируя byteы в символы с использованием codeировки UTF-8.

  • String readString (Path, Charset): работает, How метод выше, только деcodeирует byteы в символы с помощью Charset.

  • Path writeString (Path, CharSequence, java.nio.file. OpenOption []): если вы запишете последовательность символов CharSequence в файл, эти символы будут заcodeированы в byteы (с помощью UTF-8).

  • Path writeString (Path, CharSequence, java.nio.file. Charset, OpenOption []): работает, How метод выше, только codeировка символов в byteы производится с помощью Charset.
java.nio.file.Path
  • Путь (String, String []): возвращает путь (Path), преобразуя строку пути or последовательность строк, которые при объединении образуют строку пути.

  • Путь (net.URI): возвращает путь преобразуя URI.
java.util.Collection
  • Object [] toArray (java.util.function.IntFunction): возвращает массив, содержащий все элементы в этой коллекции, используя предоставленную генераторную функцию для распределения возвращаемого массива.
java.util.concurrent.PriorityBlockingQueue java.util.PriorityQueue
  • void forEach (java.util.function.Consumer): выполняет заданное действие для каждого element Iterable до тех пор, пока все элементы не будут обработаны, or действие не вызовет исключение.

  • boolean removeAll (java.util.Collection): удаляет все элементы этой коллекции, которые также содержатся в указанной коллекции (дополнительная операция).

  • boolean removeIf (java.util.function.Predicate): Удаляет все элементы этой коллекции, которые удовлетворяют заданному предикату.

  • boolean retainAll (java.util.Collection): Сохраняет только элементы в этой коллекции, которые содержатся в указанной коллекции (дополнительная операция).
java.util.concurrent.TimeUnit
  • long convert (java.time.Duration): конвертирует заданную продолжительность времени в этот юнит.
java.util.function.Predicate
  • Predicate not(Predicate): возвращает предикат, который является отрицанием поставленного предиката.
Например, следующий code:

lines.stream ()

.filter (s ->! s.isBlank ())
можно преобразовать в такой:

lines.stream ()

.filter (Predicate.not (String :: ISBLANK))
а если мы используем статический импорт, то вот что мы получим:

lines.stream ()
.filter (not(String :: ISBLANK))
java.util.Optional java.util.OptionalInt java.util.OptionalDouble java.util.OptionalLong
  • boolean isEmpty (): Если meaning отсутствует, возвращает true, в противном случае — false.
java.util.regex.Pattern
  • Predicate asMatchPredicate (): эксперт по Java Саймон Риттер полагает, что здесь может быть скрыто настоящее сокровище API JDK 11. Этот метод создает предикат, который проверяет, соответствует ли этот шаблон заданной строке ввода.
java.util.zip.Deflater
  • int deflate (ByteBuffer): сжимает входные данные и заполняет указанный буфер сжатыми данными.

  • int deflate (ByteBuffer, int): сжимает входные данные и заполняет указанный буфер сжатыми данными. returns фактическое количество сжатых данных.

  • void setDictionary (ByteBuffer): устанавливает заданный словарь для сжатия в byteы в данном буфере. Это перегруженная форма существующего метода, который теперь может принимать ByteBuffer, а не byteовый массив.

  • void setInput (ByteBuffer): Устанавливает входные данные для сжатия. Также является перегруженной формой существующего метода.
java.util.zip.Inflater
  • int inflate (ByteBuffer): распаковывает byteы в указанный буфер. returns фактическое количество несжатых byteов.

  • void setDictionary (ByteBuffer): устанавливает заданный словарь в byteы в данном буфере. Является перегруженной формой существующего метода.

  • void setInput (ByteBuffer): устанавливает входные данные для декомпрессии. Перегруженная форма существующего метода.
javax.print.attribute.standard.DialogOwner Это — новый класс в JDK 11 и он является классом атрибутов, используемый для поддержки requestов на page печати or настройки, должен отображаться поверх всех окон or определенного окна. javax.swing.DefaultComboBoxModel javax.swing.DefaultListModel
  • void addAll (Collection): добавляет все элементы, присутствующие в коллекции.

  • void addAll (int, Collection): добавляет все элементы, присутствующие в коллекции, начиная с указанного индекса.
javax.swing.ListSelectionModel
  • int [] getSelectedIndices (): возвращает массив всех выбранных индексов в выбранной модели в порядке возрастания.

  • int getSelectedItemsCount (): возвращает количество выбранных элементов.
jdk.jshell.EvalException
  • shell.JShellException getCause (): возвращает причину throwable в исполняющем клиенте, представленном этим EvalException, or null, если причины не существует or она неизвестна.

Недевелоперские фичи Java 11

[181] Nest-Based Access Control Java и другие языки поддерживают вложенные классы через внутренние классы. Whatбы это работало, компилятор должен выполнить определённые трюки. Например:

public class Outer {
    private int outerInt;

     class Inner {
       public void printOuterInt() {
         System.out.println("Outer int = " + outerInt);
       }
     }
   }
Компилятор модифицирует это, чтобы создать перед выполнением компиляции что-то вроде следующего:

public class Outer {
      private int outerInt;

      public int access$000() {
        return outerInt; 
      }

    }
 

    class Inner$Outer {

      Outer outer;

      public void printOuterInt() {
        System.out.println("Outer int = " + outer.access$000());
      }
    }
Хотя по логике внутренний класс является частью того же самого codeа, что и внешний класс, он скомпorрован How отдельный класс. Поэтому для этой операции требуется синтетический соединительный метод, который должен создать компилятором для обеспечения доступа к private-полю внешнего класса. Этот JEP представляет концепцию вложений (гнёзд), где два члена одного вложения (Outer and Inner из нашего примера) являются «друзьями по вложению». Для формата file класса определены два новых атрибута — NestHost и NestMembers. Эти изменения полезны для других языков, поддерживающих вложенные классы и bytecode. Эта функция представляет три новых метода для java.lang.Class: Class getNestHost () Class [] getNestMembers () boolean isNestmateOf (Class) [309] Dynamic Class-File Constants Этот JEP описывает расширение формата file класса для поддержки новой формы с постоянным пулом CONSTANT_Dynamic. Идея динамической константы кажется оксюмороном, но, по сути, вы можете думать о ней How о конечном значении в Java 11. Значение константы-пула не задано во время компиляции (в отличие от других констант), но использует метод начальной загрузки для определения значения во время выполнения. Поэтому meaning является динамическим, но, поскольку его meaning задано только один раз, оно также является постоянным. Эта функция в первую очередь нацелена на людей, разрабатывающих новые языки и компиляторы, которые будут генерировать byte-codeы и файлы классов в качестве вывода для запуска на JVM. [315] Improve Aarch64 Intrinsics Этот JEP предложило сообщество Red Hat. Теперь JVM может использовать больше специализированных инструкций, доступных в наборе команд Arm 64. В частности, это улучшает работу методов sin (), cos () и log () класса java.lang.Math. [318] Epsilon: A No-Op Garbage Collector Как и в случае JEP 315, за появление сборщика мусора Epsilon можете благодарить Red Hat. Epsilon необычен хотя бы тем, что на самом деле он мусор не собирает! При создании новых an objectов, он выделяет память, если это нужно, но не восстанавливает пространство, занятое незарегистрированными an objectми. «И в чём смысл?», — спросите вы. Оказывается у такой «сборки мусора» есть два вида использования:
  1. Прежде всего, этот сборщик мусора предназначен для того, чтобы новые алгоритмы GC были оценены с точки зрения их влияния на производительность. Идея состоит в том, чтобы запустить пример applications с Epsilon и сгенерировать набор показателей. Включается новый алгоритм сборки мусора, запускаются те же тесты, а затем результаты сравниваются.

  2. Для очень коротких задач (считайте безserverные функции в облаке), где вы можете гарантировать, что не превысите память, выделенную куче. Это может повысить производительность за счет отсутствия накладных расходов (включая сбор статистики, необходимой для принятия решения о запуске коллектора) в codeе applications. Если пространство кучи исчерпано, JVM может быть сконфигурирован с ошибкой одним из трех способов:
    • Вызывается обычный OutOfMemoryError.
    • Выполнить сброс кучи
    • Сбой жесткого диска JVM и, возможно, выполнение другой задачи (например, запуск отладчика).
[328]: Flight Recorder Flight Recorder — это низкоуровневая структура сбора данных для JVM. До JDK 11 это была коммерческая функция в Oracle JDK binary. Теперь Oracle устраняет функциональные различия между Oracle JDK и одним билдом из OpenJDK. Вот что делает Flight Recorder:
  • Предоставляет API для производства и потребления данных How событий
  • Предоставляет буферный механизм и формат двоичных данных
  • Разрешает настройку и фильтрацию событий
  • Предоставлять события для ОС, JVM HotSpot и библиотек JDK
Здесь появилось два новых модуля: jdk.jfr и jdk.management.jfr. [329] Криптографические алгоритмы ChaCha20 и Poly1305 Этот JEP посвящен обновлению шифров, используемых JDK. В данном случае реализованы алгоритмы шифрования ChaCha20 и ChaCha20-Poly1305, How указано в RFC 7539. ChaCha20 — это относительно новый потоковый шифр, который может заменить старый, небезопасный шифр RC4. [333] ZGC: A Scalable Low-Latency Garbage Collector Экспериментальный масштабируемый сборщик мусора с низкой задержкой. Предназначен для использования с applicationsми, для которых требуется большая (многогигаbyteная) куча и низкая задержка. Он использует кучу одного поколения и выполняет большинство (но не все) работы по сборке мусора одновременно с приложением. [332] Transport Layer Security (TLS) 1.3 TLS 1.3 (RFC 8446) — серьезная заплата протокола защиты транспортного уровня TLS, которая обеспечивает значительное повышение безопасности и производительности по сравнению с предыдущими versionми. JDK теперь поддерживает эту версию протокола. Материал основан на статье Саймона Риттера и официальной documentации.
تبصرے
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION