Особенности Java 9 с примерами

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

Java 10 уже выпущена. Для полного обзора релиза Java 10 ознакомьтесь с Java 10 Features.

Особенности Java 9

Некоторые из важных особенностей Java 9 включают;

  1. Java 9 REPL (JShell)
  2. Фабричные методы для неизменяемых списков, множеств, карт и Map.Entry
  3. Приватные методы в интерфейсах
  4. Система модулей Java 9
  5. Улучшения в Process API
  6. Улучшения в Try With Resources
  7. Улучшения в API CompletableFuture
  8. Реактивные потоки
  9. Оператор Diamond для анонимных внутренних классов
  10. Улучшения в классе Optional
  11. Улучшения в API Stream
  12. Улучшенная аннотация @Deprecated
  13. HTTP 2 Клиент
  14. API многоразрешения изображений
  15. Прочие функции Java 9

Корпорация Oracle планирует выпустить Java SE 9 примерно к концу марта 2017 года. В этом сообщении я кратко рассмотрю “Особенности Java 9” с некоторыми примерами.

Java 9 REPL (JShell)

Корпорация Oracle представила новый инструмент под названием “jshell”. Это среда выполнения Java и также известна как REPL (Read Evaluate Print Loop). Она используется для выполнения и тестирования любых конструкций Java, таких как класс, интерфейс, перечисление, объект, операторы и т. д. очень легко. Мы можем загрузить программное обеспечение JDK 9 EA (Early Access) с сайта https://jdk9.java.net/download/

G:\>jshell
|  Welcome to JShell -- Version 9-ea
|  For an introduction type: /help intro


jshell> int a = 10
a ==> 10

jshell> System.out.println("a value = " + a )
a value = 10

Если вы хотите узнать больше о инструменте REPL, пожалуйста, ознакомьтесь с Основами Java 9 REPL (часть 1) и Особенностями Java 9 REPL (часть 2).

Фабричные методы для неизменяемых списков, множеств, карт и Map.Entry

Корпорация Oracle представила несколько удобных фабричных методов для создания неизменяемых объектов списка, множества, карты и Map.Entry. Эти утилитарные методы используются для создания пустых или непустых объектов коллекций. В Java SE 8 и более ранних версиях мы можем использовать утилитарные методы класса Collections, такие как unmodifiableXXX, для создания неизменяемых объектов коллекций. Например, если мы хотим создать неизменяемый список, то мы можем использовать метод Collections.unmodifiableList. Однако эти методы Collections.unmodifiableXXX являются утомительным и многословным подходом. Чтобы преодолеть эти недостатки, корпорация Oracle добавила несколько утилитарных методов к интерфейсам List, Set и Map. У интерфейсов List и Set есть методы «of()» для создания пустых или непустых неизменяемых списков или множеств, как показано ниже: Пример пустого списка

List immutableList = List.of();

Пример непустого списка

List immutableList = List.of("one","two","three");

У карты есть два набора методов: методы of() и методы ofEntries() для создания неизменяемого объекта карты и неизменяемого объекта Map.Entry соответственно. Пример пустой карты

jshell> Map emptyImmutableMap = Map.of()
emptyImmutableMap ==> {}

Пример непустой карты

jshell> Map nonemptyImmutableMap = Map.of(1, "one", 2, "two", 3, "three")
nonemptyImmutableMap ==> {2=two, 3=three, 1=one}

Если вы хотите узнать больше о этих утилитарных методах, пожалуйста, ознакомьтесь со следующими ссылками:

Приватные методы в интерфейсах

В Java 8 мы можем предоставлять реализацию метода в интерфейсах с использованием методов по умолчанию и статических методов. Однако мы не можем создавать приватные методы в интерфейсах. Чтобы избежать избыточного кода и обеспечить большую повторяемость, корпорация Oracle собирается представить приватные методы в интерфейсах Java SE 9. С Java SE 9 и далее мы можем писать как приватные, так и приватные статические методы в интерфейсе, используя ключевое слово ‘private’. Эти приватные методы аналогичны другим приватным методам класса, между ними нет разницы.

public interface Card{

  private Long createCardID(){
    // Реализация метода идет здесь.
  }

  private static void displayCardDetails(){
    // Реализация метода идет здесь.
  }

}

Если вы хотите узнать больше об этой новой функции, пожалуйста, прочитайте эту ссылку: Приватные методы Java 9 в интерфейсе.

Система модулей Java 9

Одним из крупных изменений в Java 9 является система модулей. Корпорация Oracle собирается представить следующие функции в рамках Проекта Jigsaw.

  • Модульный JDK
  • Модульный исходный код Java
  • Модульные образы времени выполнения
  • Инкапсулирование внутренних API Java
  • Система модулей платформы Java

До версий Java SE 9 мы использовали монолитные JAR-файлы для разработки Java-приложений. Эта архитектура имеет много ограничений и недостатков. Чтобы избежать всех этих недостатков, в Java SE 9 появилась система модулей. JDK 9 поставляется с 92 модулями (количество может измениться в финальной версии). Мы можем использовать модули JDK, а также создавать свои собственные модули, как показано ниже: Простой пример модуля

module com.foo.bar { }

Здесь мы используем ‘module’ для создания простого модуля. У каждого модуля есть имя, соответствующий код и другие ресурсы. Чтобы узнать больше деталей об этой новой архитектуре и получить практический опыт, пожалуйста, ознакомьтесь с моими оригинальными учебниками здесь:

Улучшения в API процесса

Java SE 9 поставляется с некоторыми улучшениями в API процесса. Они добавили несколько новых классов и методов для упрощения управления и управления процессами ОС. Два новых интерфейса в API процесса:

Пример API процесса

 ProcessHandle currentProcess = ProcessHandle.current();
 System.out.println("Current Process Id: = " + currentProcess.getPid());

Улучшение Try With Resources

Мы знаем, что Java SE 7 ввела новую конструкцию обработки исключений: Try-With-Resources для автоматического управления ресурсами. Основная цель этого нового оператора – “Автоматическое лучшее управление ресурсами”. Java SE 9 собирается внести некоторые улучшения в этот оператор, чтобы избежать лишней длинности и улучшить читаемость. Пример Java SE 7

void testARM_Before_Java9() throws IOException{
 BufferedReader reader1 = new BufferedReader(new FileReader("journaldev.txt"));
 try (BufferedReader reader2 = reader1) {
   System.out.println(reader2.readLine());
 }
}

Пример Java 9

void testARM_Java9() throws IOException{
 BufferedReader reader1 = new BufferedReader(new FileReader("journaldev.txt"));
 try (reader1) {
   System.out.println(reader1.readLine());
 }
}

Чтобы узнать больше об этой новой функции, пожалуйста, прочтите мой оригинальный учебник по ссылке: Улучшения Try-With-Resources в Java 9

Улучшения API CompletableFuture

В Java SE 9 компания Oracle собирается улучшить API CompletableFuture для решения некоторых проблем, возникших в Java SE 8. Они собираются добавить поддержку задержек и таймаутов, некоторые утилитарные методы и улучшенное наследование.

Executor exe = CompletableFuture.delayedExecutor(50L, TimeUnit.SECONDS);

Здесь delayedExecutor() – это статический утилитарный метод, используемый для возврата нового исполнителя, который отправляет задачу исполнителю по умолчанию после заданной задержки.

Реактивные потоки

В наше время Реактивное программирование стало очень популярным при разработке приложений для получения прекрасных преимуществ. Фреймворки Scala, Play, Akka и т. д. уже интегрировали Реактивные потоки и получают много преимуществ. Компания Oracle также представляет новый API Реактивных потоков в Java SE 9. API Реактивных потоков Java SE 9 – это фреймворк Publish/Subscribe для реализации асинхронных, масштабируемых и параллельных приложений очень легко с использованием языка Java. Java SE 9 представила следующий API для разработки Реактивных потоков в приложениях на основе Java.

  • java.util.concurrent.Flow
  • java.util.concurrent.Flow.Publisher
  • java.util.concurrent.Flow.Subscriber
  • java.util.concurrent.Flow.Processor

Читайте больше на Java 9 Reactive Streams.

Алмазный оператор для анонимного внутреннего класса

Мы знаем, что Java SE 7 ввела одну новую функцию: алмазный оператор для избежания избыточного кода и излишней длинности для повышения читаемости. Однако в Java SE 8 Oracle Corp (разработчик библиотеки Java) обнаружила некоторые ограничения в использовании алмазного оператора с анонимным внутренним классом. Они исправили эти проблемы и собираются выпустить их в качестве части Java 9.

  public List getEmployee(String empid){
     // Код для получения информации о сотруднике из хранилища данных
     return new List(emp){ };
  }

Здесь мы используем только “Список” без указания параметра типа.

Улучшения класса Optional

В Java SE 9 корпорация Oracle добавила несколько полезных новых методов в класс java.util.Optional. Здесь я собираюсь обсудить один из этих методов на примере: метод stream. Если значение присутствует в данном объекте Optional, этот метод stream() возвращает последовательный поток с этим значением. В противном случае он возвращает пустой поток. Они добавили метод “stream()” для работы с объектами Optional лениво, как показано ниже:

Stream<Optional> emp = getEmployee(id)
Stream empStream = emp.flatMap(Optional::stream)

Здесь используется метод Optional.stream() для преобразования потока Optional объектов типа Employee в поток объектов Employee, чтобы мы могли лениво работать с этим результатом в коде. Чтобы узнать больше об этой функции с примерами и ознакомиться с новыми методами, добавленными в класс Optional, пожалуйста, ознакомьтесь с моим оригинальным учебным пособием по ссылке: Java SE 9: Улучшения класса Optional

Улучшения в API потоков

На Java SE 9 Oracle Corp добавила четыре полезных новых метода в интерфейс java.util.Stream. Поскольку Stream – это интерфейс, все эти новые методы реализованы как методы по умолчанию. Два из них очень важны: методы dropWhile и takeWhile. Если вы знакомы с языком Scala или любым функциональным языком программирования, вы определенно знаете об этих методах. Они очень полезны при написании кода в функциональном стиле. Давайте обсудим здесь метод takeWhile. Этот метод takeWhile() принимает предикат в качестве аргумента и возвращает поток подмножества значений данного потока до тех пор, пока предикат в первый раз не вернет false. Если первое значение не удовлетворяет этому предикату, он просто возвращает пустой поток.

jshell> Stream.of(1,2,3,4,5,6,7,8,9,10).takeWhile(i -> i < 5 )
                 .forEach(System.out::println);
1
2
3
4

Чтобы узнать больше о методах takeWhile и dropWhile, а также о других новых методах, пожалуйста, прочитайте мой оригинальный учебник по ссылке: Java SE 9: Улучшения в Stream API

Усовершенствованная @Deprecated аннотация

В Java SE 8 и более ранних версиях, аннотация @Deprecated представляет собой всего лишь маркерный интерфейс без каких-либо методов. Она используется для пометки Java API, такого как класс, поле, метод, интерфейс, конструктор, перечисление и т. д. В Java SE 9 Oracle Corp улучшила аннотацию @Deprecated, чтобы предоставить более подробную информацию об устаревшем API, а также предоставила инструмент для анализа статического использования устаревших API в приложении. Они добавили два метода в этот интерфейс Deprecated: forRemoval и since, чтобы обеспечить эту информацию.

HTTP 2 Client

В Java SE 9 корпорация Oracle собирается выпустить новый API клиента HTTP 2 для поддержки протокола HTTP/2 и функций WebSocket. У существующего или устаревшего API клиента HTTP есть множество проблем (например, поддерживает протокол HTTP/1.1 и не поддерживает протокол HTTP/2 и WebSocket, работает только в блокирующем режиме, а также имеет множество проблем с производительностью). Поэтому они заменяют API HttpURLConnection новым HTTP-клиентом. Они собираются представить новый API клиента HTTP 2 в пакете “java.net.http”. Он поддерживает протоколы HTTP/1.1 и HTTP/2. Поддерживает как синхронный (блокирующий режим), так и асинхронный режимы. Поддерживает асинхронный режим с использованием API WebSocket. Вы можете ознакомиться с этим новым API по адресу https://download.java.net/java/jdk9/docs/api/java/net/http/package-summary.html Пример клиента HTTP 2

jshell> import java.net.http.*

jshell> import static java.net.http.HttpRequest.*

jshell> import static java.net.http.HttpResponse.*

jshell> URI uri = new URI("https://rams4java.blogspot.co.uk/2016/05/java-news.html")
uri ==> https://rams4java.blogspot.co.uk/2016/05/java-news.html

jshell> HttpResponse response = HttpRequest.create(uri).body(noBody()).GET().response()
response ==> java.net.http.HttpResponseImpl@79efed2d

jshell> System.out.println("Response was " + response.body(asString()))

Пожалуйста, ознакомьтесь с моим оригинальным учебником по ссылке: Java SE 9: HTTP 2 Client, чтобы понять протокол HTTP/2 и WebSocket, преимущества нового API и недостатки старого API с примерами.

API многоразрешения изображения

В Java SE 9 корпорация Oracle собирается представить новый API многоразрешения изображения. Важный интерфейс в этом API – MultiResolutionImage. Он доступен в пакете java.awt.image. MultiResolutionImage инкапсулирует набор изображений с разными высотами и ширинами (разными разрешениями) и позволяет нам запросить их в соответствии с нашими требованиями.

Различные возможности Java 9

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

  • Улучшения сборщика мусора (Garbage Collector)
  • API для обхода стека (Stack-Walking)
  • Фильтрация входящих данных сериализации
  • Устаревший API для апплетов (Applet)
  • Индивидуализация конкатенации строк (Indify String Concatenation)
  • Расширенные методические обработчики (Enhanced Method Handles)
  • API и сервис регистрации для логирования платформы Java (Java Platform Logging)
  • Компактные строки (Compact Strings)
  • API парсера для Nashorn
  • Поиск в Javadoc
  • HTML5 Javadoc

I will pickup these java 9 features one by one and update them with enough description and examples. That’s all about Java 9 features in brief with examples.

Source:
https://www.digitalocean.com/community/tutorials/java-9-features-with-examples