Java 9 нови функции

1. Общ преглед

Java 9 се предлага с богат набор от функции. Въпреки че няма нови езикови концепции, новите API и диагностични команди определено ще бъдат интересни за разработчиците.

В тази статия ще имаме бърз поглед на високо ниво на някои от новите функции; пълен списък с нови функции можете да намерите тук.

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

Нека започнем с голямата - внасяне на модулност в платформата Java.

Модулната система предоставя възможности, подобни на системата на OSGi framework. Модулите имат концепция за зависимости, могат да експортират публичен API и да пазят подробностите за изпълнението скрити / частни.

Една от основните мотивации тук е да се осигури модулна JVM, която може да работи на устройства с много по-малко налична памет. JVM може да работи само с тези модули и API, които се изискват от приложението. Вижте тази връзка за описание на това какви са тези модули.

Също така, JVM вътрешните (внедряващи) API като com.sun. * Вече не са достъпни от кода на приложението.

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

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

Нашият модулен автомобил изисква двигател на модула да работи и изнася пакет за обработка .

За по-задълбочен пример проверете мозайката на проекта OpenJDK: Ръководство за бързо стартиране на модулната система.

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

Дългоочаквана подмяна на старата HttpURLConnection .

Новият API се намира под пакета java.net.http .

Той трябва да поддържа HTTP / 2 протокол и WebSocket ръкостискане, с производителност, която трябва да бъде сравнима с Apache HttpClient, Netty и Jetty.

Нека разгледаме тази нова функционалност, като създадем и изпратим проста HTTP заявка.

Актуализация: HTTP клиентският JEP се премества в модула Incubator, така че вече не е наличен в пакета java.net.http и вместо това е достъпен под jdk.incubator.http.

3.1. БЪРЗО ИЗИСКВАНЕ

API използва модела Builder, което го прави наистина лесен за бързо използване:

HttpRequest request = HttpRequest.newBuilder() .uri(new URI("//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();

В сегашния метод връща обект, представляващ процес на JVM изпълнява в момента. Най Информация подклас дава подробности за процеса.

4.2. Унищожаващи процеси

Сега - нека спрем всички работещи дъщерни процеси, използвайки kill () :

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. Разширение за диамантен оператор

Сега можем да използваме диамантен оператор заедно с анонимни вътрешни класове:

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 могат да имат частни методи, които могат да се използват за разделяне на дълги методи по подразбиране:

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 се чете – eval – print loop - REPL за кратко.

Най-просто казано, това е интерактивен инструмент за оценка на декларации, изрази и изрази на Java, заедно с API. Много е удобно за тестване на малки кодови фрагменти, които иначе изискват създаване на нов клас с основния метод.

В jshell самия изпълним могат да бъдат намерени в / бин папка:

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 процеса и да променяме неговите стартови параметри.

Можете да разберете всички налични VM флагове с подкоманда jcmd 14056 VM.flags -all

8. API за изображения с много разделителна способност

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

Класът java.awt.Graphics получава вариант от изображение с много разделителна способност въз основа на текущата DPI метрика на дисплея и всички приложени трансформации.

The class java.awt.image.BaseMultiResolutionImage provides basic implementation:

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

9. Variable Handles

The API resides under java.lang.invoke and consists of VarHandle and MethodHandles. It provides equivalents of java.util.concurrent.atomic and sun.misc.Unsafe operations upon object fields and array elements with similar performance.

With Java 9 Modular system access to sun.misc.Unsafe will not be possible from application code.

10. Publish-Subscribe Framework

The class java.util.concurrent.Flow provides interfaces that support the Reactive Streams publish-subscribe framework. These interfaces support interoperability across a number of asynchronous systems running on JVMs.

We can use utility class SubmissionPublisher to create custom components.

11. Unified JVM Logging

This feature introduces a common logging system for all components of the JVM. It provides the infrastructure to do the logging, but it does not add the actual logging calls from all JVM components. It also does not add logging to Java code in the JDK.

The logging framework defines a set of tags – for example, gc, compiler, threads, etc. We can use the command line parameter -Xlog to turn on logging during startup.

Let's log messages tagged with ‘gc' tag using ‘debug' level to a file called ‘gc.txt' with no decorations:

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

-Xlog:help will output possible options and examples. Logging configuration can be modified runtime using jcmd command. We are going to set GC logs to info and redirect them to a file – gc_logs:

jcmd 9615 VM.log output=gc_logs what=gc

12. New APIs

12.1. Immutable Set

java.util.Set.of() – creates an immutable set of a given elements. In Java 8 creating a Set of several elements would require several lines of code. Now we can do it as simple as:

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

The Set returned by this method is JVM internal class: java.util.ImmutableCollections.SetN, which extends public java.util.AbstractSet. It is immutable – if we try to add or remove elements, an UnsupportedOperationException will be thrown.

You can also convert an entire array into a Set with the same method.

12.2. Optional to Stream

java.util.Optional.stream() gives us an easy way to you use the power of Streams on Optional elements:

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

13. Conclusion

Java 9 ще се предлага с модулна JVM и много други нови и разнообразни подобрения и функции.

Можете да намерите изходния код за примерите на GitHub.