- Нововведения в Java 9: разбираем на примерах
- JShell
- Private методы в интерфейсах
- Модульная система
- Улучшение API
- Новшества в CompletableFuture API
- Реактивное программирование
- Diamond оператор для анонимных классов
- Дополнительные улучшения в классах
- Улучшения Stream API
- Расширенные аннотации @Deprecated
- HTTP/2 клиент
- API для изображений с разными разрешениями
- Другие изменения
Нововведения в Java 9: разбираем на примерах
Ожидается, что новая версия Java 9 выйдет уже 27 июля 2017 года. Давайте разберёмся, какие функции появятся, и расскажем, зачем они нужны.
Вот список важных нововведений Java 9:
- JShell;
- Immutable List, Set и Map из коробки;
- Private методы в интерфейсах;
- Модульная система;
- Улучшение API;
- Изменения в try-with-resources;
- Реактивное программирование;
- Diamond оператор для анонимных классов;
- Дополнительные улучшения в классах;
- Улучшения Stream API;
- Расширенные аннотации @Deprecated;
- HTTP/2 клиент;
- API отзывчивых изображений;
- Разное.
С помощью примеров расскажем подробнее об этих функциях.
JShell
REPL (англ. read-eval-print loop) — система для интерактивного программирования в консоли. То есть если пользователь вводит строку кода, в консоли появляется результат её выполнения и этот процесс повторяется.
Oracle представила новый инструмент под названием «JShell». Он используется для тестирования и использования в консоли разных конструкций, например классов, интерфейсов, перечислений, объектов, операторов и т.д.
Кстати, уже сейчас можно загрузить бета-версию JDK 9, скачав её с официального сайта .
Простейший пример работы с JShell:
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 StaticObjects">Неизменяемые объекты List, Set и Map «из коробки» Oracle представила несколько удобных методов для создания неизменяемых List, Set, Map и Map.Entry
объектов без использования дополнительных классов
В Java SE 8 и более ранних версиях мы можем использовать Collections.unmodifiableXXX
для создания неизменяемых объектов коллекций. К примеру, если мы хотим создать Immutable List
, мы будем использовать Collections.unmodifiableList
метод.
Однако это неудобно, поэтому Oracle добавила несколько вспомогательных методов в интерфейсы List, Set и Map.
Java-разработчик в отдел развития ITSM систем Открытие, Удалённо, По итогам собеседования tproger.ru Вакансии на tproger.ru List и Set интерфейсы имеют of()
методы. Примеры их использования можно увидеть ниже:
List immutableList = List.of(); // пустой неизменяемый список List immutableList = List.of("one","two","three"); // неизменяемый список, содержащий информацию
Map имеет два набора методов: of() методы и ofEntries() методы для создания объектов Immutable Map и Map.Entry.
jshell> Map emptyImmutableMap = Map.of() emptyImmutableMap ==> <> // пустое неизменяемое отображение jshell> Map nonemptyImmutableMap = Map.of(1, "one", 2, "two", 3, "three") nonemptyImmutableMap ==> // неизменяемое отображение
Private методы в интерфейсах
В Java 8 мы можем обеспечивать реализацию метода в интерфейсах, используя default и static методы. Однако мы не можем создавать private методы в интерфейсах.
Для избавления от нагромождения и переизбытка кода Oracle собирается добавить private методы в интерфейсы Java SE 9. Начиная с девятой версии, мы также сможем создавать private static методы в интерфейсах с помощью private.
Создание реализации метода для интерфейса по умолчанию:
public interface Card < private Long createCardID() < // Реализация метода происходит здесь. >private static void displayCardDetails() < // Реализация метода происходит здесь. >>
Модульная система
Одним из самых значительных изменений является появление модульной системы. До Java 9 мы использовали JAR-файлы для разработки приложений, базирующихся на Java. Однако, эта архитектура имеет несколько ограничений и недостатков. Для их устранения и внедрили модульную систему . Это нововведение является частью проекта Jigsaw , который разрабатывается для того, чтобы программисты могли разбивать программы на независимые и межпрограммные модули.
Вот некоторые из функций этой системы:
- модульная JDK;
- модульный исходный код Java;
- модульные run-time изображения;
- инкапсуляция внутренних API;
- система модульной платформы;
JDK 9 поставляется с 92 модулями. Мы можем использовать их или создать свои, например:
Каждый модуль имеет имя, связанный код и другие ресурсы.
Улучшение API
Ожидается, что в Java SE 9 будут произведены улучшения по части API. Будут добавлены несколько новых классов и методов для более удобного управления действиями операционной системы.
Два новых интерфейса в Process API:
ProcessHandle currentProcess = ProcessHandle.current(); System.out.println("Current Process Id: font-weight: 400;">Здесь нами был создан объект типа ProcessHandle для работы с действиями операционной системе. Изменения в 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()); >>
void testARM_Java9() throws IOException < BufferedReader reader1 = new BufferedReader(new FileReader("journaldev.txt")); try (reader1) < System.out.println(reader1.readLine()); >>
Можно заметить, что в новой версии, после try не обязательно объявлять новую переменную.
Новшества в CompletableFuture API
В Java 9 Oracle также собирается улучшить CompletableFuture API для решения проблем, появившихся в Java SE 8. В планах добавить задержки и тайм-ауты, дополнительные методы и улучшить подклассы.
Executor exe = CompletableFuture.delayedExecutor(50L, TimeUnit.SECONDS);
Здесь delayedExecutor() — static метод, используемый для возврата исполнителя, после заданной задержки.
Реактивное программирование
Для тех, кто ещё не знаком с парадигмой реактивного программирования, советуем прочитать наше введение в тему с примерами.
В Scala, Play, Akka уже были интегрированы reactive streams. Oracle решила добавить Reactive Streams API в Java SE 9.
Java SE 9 Reactive Streams API — фреймворк для реализации асинхронных, масштабируемых и параллельных приложений с использованием Java.
В Java SE 9 появятся следующие API:
- java.util.concurrent.Flow;
- java.util.concurrent.Flow.Publisher;
- java.util.concurrent.Flow.Subscriber;
- java.util.concurrent.Flow.Processor.
Diamond оператор для анонимных классов
Предположим, что у нас есть класс Box и мы хотим сделать его анонимным.
Вот как выглядит этот процесс в Java 8:
Box createBox(T content) < // Нужно поставить 'T' здесь :( return new Box(content) < >; >
Разве не очевидно, что Box должен быть типа T? Компилятор в случае не-анонимного класса выбрал бы нужный тип, так почему бы не сделать то же самое с анонимным?
Проблема в не обозначаемых (англ. non-denotable) типах, которые распознаются компилятором, а JVM — нет. (Такой случай может быть обработан компилятором, но вопрос — как корректно передать его JVM.)
Поэтому Diamond оператор не допускался в использовании с анонимными классами. Теперь же это возможно.
Вот как это выглядит в Java 9:
class inJava < Box createBox(T content) < // Java 9 выводит ‘T’, потому что этот тип обозначаемый return new Box<>(content) < >; > Box innerList = Arrays.asList(content); // А этот тип не выводится, так как не можем его обозначить: // return new Box<>(innerList) < >; // Вместо этого обозначаем тот тип, который нам нужен: return new Box>(innerList) < >; > >
Дополнительные улучшения в классах
В Java SE 9 Oracle добавила несколько полезных методов в java.util.Optional.
Вот например как работает метод stream:
Stream emp = getEmployee(id); Stream empStream = emp.flatMap(Optional::stream);
Здесь используется метод Optional.stream(), который конвертирует всё в поток Employee.
Улучшения Stream API
В новой версии появятся как минимум четыре метода java.util.Stream . Как и stream, все они будут стандартными. Наиболее важными являются dropWhile и takeWhile методы.
Если вы знакомы с языком Scala или функциональным программированием, вы обязательно узнаете эти методы.
Простейшее применение stream:
jshell> Stream.of(1,2,3,4,5,6,7,8,9,10).takeWhile(i -> i < 5 ).forEach(System.out::println);
Расширенные аннотации @Deprecated
До Java 9 @Deprecated — просто интерфейс-маркер. Многие разработчики предлагали Oracle улучшить информирование об устаревших возможностях API . Их услышали и добавили возможности работы с устаревшими API. Например, появились инструменты для их анализа — forRemoval и since .
HTTP/2 клиент
Oracle планирует выкатить новый HTTP-клиент для поддержки протоколов HTTP/2 и WebSocket. Они заменяют HttpURLConnection API на новый, более производительный.
Новый API будет представлен в пакете «java.net.http». Он поддерживает как синхронный, так и асинхронный режимы.
jshell> import java.net.http.* jshell> import static java.net.http.HttpRequest.* jshell> import static java.net.http.HttpResponse.* jshell> URI uri = new URI("http://rams4java.blogspot.co.uk/2016/05/java-news.html") uri ==> http://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()))
API для изображений с разными разрешениями
Oracle планирует внедрить новый API для изображений разных разрешений. Наиболее важным является интерфейс MultiResolutionImage доступный в пакете java.awt.image .
Другие изменения
Помимо вышеперечисленных изменений, ожидаются и другие. Вот лишь некоторые из них: