Java 9 Новые возможности

Java 9 Новые возможности

1. обзор

Java 9 поставляется с богатым набором функций. Хотя нет новых концепций языка, новые API и диагностические команды определенно будут интересны для разработчиков.

В этой статье мы кратко рассмотрим некоторые новые функции; доступен полный список новых функцийhere.

2. Модульная система - Jigsaw Project

Начнем с большого - внесения модульности в платформу Java.

Модульная система предоставляет возможности, аналогичные системе OSGi framework. Модули имеют концепцию зависимостей, могут экспортировать общедоступный API и сохранять детали реализации скрытыми / частными.

Одним из основных мотивов здесь является предоставление модульной JVM, которая может работать на устройствах с гораздо меньшим объемом доступной памяти. JVM может работать только с теми модулями и API, которые требуются приложению. Посмотритеthis link, чтобы узнать, что это за модули.

Кроме того, внутренние (реализация) API JVM, такие какcom.sun.*, больше не доступны из кода приложения.

Проще говоря, модули будут описаны в файле с именемmodule-info.java, расположенном в верхней части иерархии Java-кода:

module com.example.java9.modules.car {
    requires com.example.java9.modules.engines;
    exports com.example.java9.modules.car.handling;
}

Нашему модулюcar требуется для запуска модульengine, и он экспортирует пакет дляhandling.

Для более подробного примера проверьте OpenJDKProject Jigsaw: Module System Quick-Start Guide.

3. Новый HTTP-клиент

Долгожданная замена старогоHttpURLConnection.

Новый API находится в пакетеjava.net.http.

Он должен поддерживать какHTTP/2 protocol, так иWebSocket рукопожатие, с производительностью, которая должна быть сопоставима сApache HttpClient,Netty иJetty.

Давайте взглянем на эту новую функциональность, создав и отправив простой HTTP-запрос.

Обновление:HTTP Client JEP перемещается в модуль инкубатора, поэтому он больше не доступен в пакетеjava.net.http и вместо этого доступен вjdk.incubator.http.

3.1. Быстрый запрос GET

API использует шаблон Builder, что делает его действительно простым для быстрого использования:

HttpRequest request = HttpRequest.newBuilder()
  .uri(new URI("https://postman-echo.com/get"))
  .GET()
  .build();

HttpResponse response = HttpClient.newHttpClient()
  .send(request, HttpResponse.BodyHandler.asString());

4. API процесса

API процесса был улучшен для контроля и управления процессами операционной системы.

4.1. Обрабатывать информацию

Классjava.lang.ProcessHandle содержит большинство новых функций:

ProcessHandle self = ProcessHandle.current();
long PID = self.getPid();
ProcessHandle.Info procInfo = self.info();

Optional args = procInfo.arguments();
Optional cmd =  procInfo.commandLine();
Optional startTime = procInfo.startInstant();
Optional cpuUsage = procInfo.totalCpuDuration();

Методcurrent возвращает объект, представляющий процесс запущенной в данный момент JVM. ПодклассInfo предоставляет подробную информацию о процессе.

4.2. Разрушающие процессы

А теперь остановим все запущенные дочерние процессы с помощьюdestroy():

childProc = ProcessHandle.current().children();
childProc.forEach(procHandle -> {
    assertTrue("Could not kill process " + procHandle.getPid(), procHandle.destroy());
});

5. Небольшие языковые модификации

5.1. Попробуйте-с-ресурсами

В Java 7 синтаксисtry-with-resources требует объявления новой переменной для каждого ресурса, которым управляет оператор.

В Java 9 есть дополнительное уточнение: если на ресурс ссылается конечная или фактически конечная переменная, оператор try-with-resources может управлять ресурсом без объявления новой переменной:

MyAutoCloseable mac = new MyAutoCloseable();
try (mac) {
    // do some stuff with mac
}

try (new MyAutoCloseable() { }.finalWrapper.finalCloseable) {
   // do some stuff with finalCloseable
} catch (Exception ex) { }

5.2. Расширение Diamond Operator

Теперь мы можем использовать оператор diamond в сочетании с анонимными внутренними классами:

FooClass fc = new FooClass<>(1) { // anonymous inner class
};

FooClass fc0 = new FooClass<>(1) {
    // anonymous inner class
};

FooClass fc1 = new FooClass<>(1) { // anonymous inner class
};

5.3. Частный метод интерфейса

Интерфейсы в будущей версии JVM могут иметь методыprivate, которые можно использовать для разделения длинных методов по умолчанию:

interface InterfaceWithPrivateMethods {

    private static String staticPrivate() {
        return "static private";
    }

    private String instancePrivate() {
        return "instance private";
    }

    default void check() {
        String result = staticPrivate();
        InterfaceWithPrivateMethods pvt = new InterfaceWithPrivateMethods() {
            // anonymous class
        };
        result = pvt.instancePrivate();
    }
}}

6. Инструмент командной строки JShell

JShell - это цикл чтения – оценки – печати, сокращенно REPL.

Проще говоря, это интерактивный инструмент для оценки объявлений, операторов и выражений Java вместе с API. Это очень удобно для тестирования небольших фрагментов кода, которые в противном случае потребовали бы создания нового класса с методомmain.

Сам исполняемый файлjshell находится в папке<JAVA_HOME>/bin:

jdk-9\bin>jshell.exe
|  Welcome to JShell -- Version 9
|  For an introduction type: /help intro
jshell> "This is my long string. I want a part of it".substring(8,19);
$5 ==> "my long string"

Интерактивная оболочка поставляется с историей и автозаполнением; он также предоставляет такие функции, как сохранение и загрузка из файлов всех или некоторых письменных операторов:

jshell> /save c:\develop\JShell_hello_world.txt
jshell> /open c:\develop\JShell_hello_world.txt
Hello JShell!

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

7. Подкоманды JCMD

Давайте рассмотрим некоторые из новых подкоманд в утилите командной строкиjcmd. Мы получим список всех классов, загруженных в JVM, и их структуру наследования.

В приведенном ниже примере мы видим иерархиюjava.lang.Socket, загруженных в JVM под управлением Eclipse Neon:

jdk-9\bin>jcmd 14056 VM.class_hierarchy -i -s java.net.Socket
14056:
java.lang.Object/null
|--java.net.Socket/null
|  implements java.io.Closeable/null (declared intf)
|  implements java.lang.AutoCloseable/null (inherited intf)
|  |--org.eclipse.ecf.internal.provider.filetransfer.httpclient4.CloseMonitoringSocket
|  |  implements java.lang.AutoCloseable/null (inherited intf)
|  |  implements java.io.Closeable/null (inherited intf)
|  |--javax.net.ssl.SSLSocket/null
|  |  implements java.lang.AutoCloseable/null (inherited intf)
|  |  implements java.io.Closeable/null (inherited intf)

Первый параметр командыjcmd - это идентификатор процесса (PID) JVM, на котором мы хотим запустить команду.

Еще одна интересная подкоманда -set_vmflag. Мы можем изменять некоторые параметры JVM в режиме онлайн без необходимости перезапуска процесса JVM и изменения его параметров запуска.

Вы можете узнать все доступные флаги ВМ с помощью подкомандыjcmd 14056 VM.flags -all

8. API изображений с несколькими разрешениями

Интерфейсjava.awt.image.MultiResolutionImage инкапсулирует набор изображений с разным разрешением в один объект. Мы можем извлечь вариант изображения с определенным разрешением на основе заданной метрики DPI и набора преобразований изображения или получить все варианты изображения.

Классjava.awt.Graphics получает вариант из изображения с несколькими разрешениями на основе текущей метрики DPI дисплея и любых примененных преобразований.

Классjava.awt.image.BaseMultiResolutionImage обеспечивает базовую реализацию:

BufferedImage[] resolutionVariants = ....
MultiResolutionImage bmrImage
  = new BaseMultiResolutionImage(baseIndex, resolutionVariants);
Image testRVImage = bmrImage.getResolutionVariant(16, 16);
assertSame("Images should be the same", testRVImage, resolutionVariants[3]);

9. Переменные ручки

API находится вjava.lang.invoke и состоит изVarHandle иMethodHandles. Он обеспечивает эквиваленты операцийjava.util.concurrent.atomic иsun.misc.Unsafe над полями объектов и элементами массива с аналогичной производительностью.

В модульной системе Java 9 доступ кsun.misc.Unsafe из кода приложения будет невозможен.

10. Платформа публикации и подписки

Классjava.util.concurrent.Flow предоставляет интерфейсы, которые поддерживают структуру публикации-подпискиReactive Streams. Эти интерфейсы поддерживают взаимодействие в ряде асинхронных систем, работающих на JVM.

Мы можем использовать служебный классSubmissionPublisher для создания пользовательских компонентов.

11. Единое ведение журнала JVM

Эта функция вводит общую систему регистрации для всех компонентов JVM. Он предоставляет инфраструктуру для ведения журналов, но не добавляет фактических вызовов журналирования от всех компонентов JVM. Это также не добавляет запись в код Java в JDK.

Платформа ведения журнала определяет наборtags - например,gc,compiler,threads и т. Д. Мы можем использовать параметр командной строки-Xlog, чтобы включить ведение журнала во время запуска.

Давайте записывать сообщения, помеченные тегом «gc», на уровне «отладки» в файл с именем «gc.txt» без украшений:

java -Xlog:gc=debug:file=gc.txt:none ...

-Xlog:help выведет возможные варианты и примеры. Конфигурацию ведения журнала можно изменить во время выполнения с помощью командыjcmd. Мы собираемся установить для журналов GC информацию и перенаправить их в файл - gc_logs:

jcmd 9615 VM.log output=gc_logs what=gc

12. Новые API

12.1. Неизменяемый набор

java.util.Set.of() - создает неизменяемый набор заданных элементов. В Java 8 создание набора из нескольких элементов потребует нескольких строк кода. Теперь мы можем сделать это так просто:

Set strKeySet = Set.of("key1", "key2", "key3");

Set, возвращаемый этим методом, является внутренним классом JVM:java.util.ImmutableCollections.SetN, который расширяет общедоступныйjava.util.AbstractSet. Он неизменен - ​​если мы попытаемся добавить или удалить элементы, будет выброшенUnsupportedOperationException.

Вы также можете преобразовать весь массив вSet тем же методом.

12.2. Необязательно для потоковой передачи

java.util.Optional.stream() дает нам простой способ использовать возможности Streams для необязательных элементов:

List filteredList = listOfOptionals.stream()
  .flatMap(Optional::stream)
  .collect(Collectors.toList());

13. Заключение

Java 9 будет поставляться с модульной JVM и множеством других новых и разнообразных улучшений и функций.

Вы можете найти исходный код примеровover on GitHub.