Всем доброго времени суток. В ноябре 2017 в Санкт-Петербурге прошло одно из самых примечательных событий года для отечественных Java-разработчиков: конференция Joker. На конференции было озвучено много тем, такие как GC, Concurrency, Spring Boot, JUnit 5 и другие, презентации по которым вы можете найти в открытом доступе на сайте конференции. Перечислять все смысла нет, так как по каждому топику можно составить отдельную статью с примерами и выдержками. Поэтому остановимся на главном.
Основной темой были нововведения в Java 9: ей посвятили аж две лекции, по модулям, и по всему остальному. Саму девятку Oracle изначально планировали выпустить еще в середине лета 2016, однако релиз был перенесен сначала на полгода, а потом и вовсе на вторую половину 2017. И вот, 21 сентября 2017, выход девятки состоялся.
Данная статья представлена именно как обзор новоиспеченной джавы, так как тема сама по себе большая, требующая целого цикла статей, которые, несомненно, б��дут при поступлении просьб от трудящихся.
Итак, по порядку. Как говорилось выше, нововведения в девятке можно разделить на два блока: общий и модульный. Придерживаясь хронологии Joker, начнем с первого.
На самом деле литералы в коллекциях можно использовать с 7 версии, никто не запрещает выполнить следующее, если у вас установлен ProjectCoin:
В 9 версии вы можете использовать нечто подобное без каких-либо предварительных подготовок:
или
Так же было сказано несколько слов о generic Pair, а вернее об их отсутствии. Однако в 9 появился усовершенствованный костыль использования мапы в качестве пары:
Ждем Project Valhalla.
На самом деле этот оператор реализован на Groovy на синтаксическом уровне, но если вы попробуете написать на джаве нечто подобное
компилятор предсказуемо ругнется. В девятке внедрили подобную логику, правда не на уровне синтаксиса. Ниже приведены два эквивалентных выражения на девятке и в уже привычном виде.
Если кратко, этот класс для сбора not-null объектов: вместо того, чтобы проводить null-проверки, можно складывать объекты в данный контейнер, который автоматически будет отсеивать несуществующие объекты. Появился в Java 8 и вполне логично, что в новой версии появились улучшения для данного класса. Метод or интуитивно понятен: будет возвращен вызывающий объект, если он не нулевой, в противном случае вернется аргумент.
Следующий метод выполняет заданное действие над значением, если оно присутствует, в противном случае будет выполнено некое дефолтное значение.
Если значение присутствует, возвращает стрим только с этим значением, в противном случае стрим будет пустым.
Возможность использовать flatMap для удаления нулевых результатов:
Появился целый ряд методов API, из которых можно получить стримы: Scanner.tokens, Matcher.results, ServiceLoader.stream, LocalDate.datesUntil,
StackWalker.walk, ClassLoader.resources, Process.children/descendants,
Catalog.catalogs, DriverManager.drivers. В самих стримах тоже появились новые методы takeWhile, dropWhile, а также новые сборщики flatMapping, filtering.
Тут все также масштабно. Появилась возможность считывать байты с поступающего потока
Перенаправлять байты с входящего потока на исходящий: InputStream.transferTo(OutputStream).
Появилась возможность разбить принимаемый классом Scanner объект на токены в виде отдельных стримов:
Matcher.stream и Scanner.findAll выдают поток найденных результатов:
Matcher.replaceFirst/replaceAll теперь могут принимать на вход функцию, согласно которой будет произведена перестановка:
Тут появился целый интерфейс ProcessHandle, позволяющий контролировать нативные процессы. С его помощью можно мониторить жив ли процесс, информацию о нем, лист детей и прочие плюшки. Зачем он нужен, когда есть абстрактный класс Process, спросите вы. На самом деле ProcessHandle предоставляет гораздо больше возможностей, нежели Process. Последний в свою очередь также предоставляет доступ к IOE потокам, что сказывается на производительности.
Интерфейсы теперь могут иметь методы с модификаторами доступа private, private static и судя по всему в скором времени совсем перестанут быть интерфейсами. Нижнее подчеркивание _ больше не может являться именем переменной — гайки закручиваются. И, наконец, поддержка try-with-resources
Появилось несколько деприкаций, куда же без этого. Классы Observable, Observer с новой версии будут считаться устаревшими, так же как и Object.finalize, Runtime.runFinalizersOnExit. Class.newInstance также теперь относят к Deprecated и аргументируют это тем, что он бросает проверяемые исключения конструктора без объявления их. Под ту же аннотацию попал весь Applet API, a также ряд модулей: java.activation, java.corba, java.transaction, java.xml.bind, java.xml.ws. Здесь были перечислены основные вещи, попавшие под аннотацию Deprecated и в презентацию Хорстмана, полный список всегда можно посмотреть у оракла.
Теперь этот код вернет значение «9», а не «1.9.0.».
Также в Java 9 появилась модульность, которая вызвала бОльший шум, чем все вышеперечисленное. И это неудивительно, так как статистика показывает, что это модульность была наиболее ожидаемой фичей среди разработчиков

Были вопросы что это вообще такое, как это будет взаимодействовать с Maven. Половина доклада ушла на обзор OSGi, вторая половина на обзор Jigsaw и объяснение почему это круто, превосходит по всем параметрам предмет первой половины доклада и то, что Jigsaw незаслуженно скромно принимается обществом. Судить об успешности этого проекта мы действительно можем только от общества, а пока нам остается ждать глобального перехода на Java 9, который, как сказали сами докладчики, будет происходить ближайшие 2-3 года. А пока можно посмотреть на самые ожидаемые изменения в следующей версии джавы и слушать шутки о том, будет ли она называться Java 10 или Java X.

Основной темой были нововведения в Java 9: ей посвятили аж две лекции, по модулям, и по всему остальному. Саму девятку Oracle изначально планировали выпустить еще в середине лета 2016, однако релиз был перенесен сначала на полгода, а потом и вовсе на вторую половину 2017. И вот, 21 сентября 2017, выход девятки состоялся.
Данная статья представлена именно как обзор новоиспеченной джавы, так как тема сама по себе большая, требующая целого цикла статей, которые, несомненно, б��дут при поступлении просьб от трудящихся.
Итак, по порядку. Как говорилось выше, нововведения в девятке можно разделить на два блока: общий и модульный. Придерживаясь хронологии Joker, начнем с первого.
1. Появление литералов в коллекциях
На самом деле литералы в коллекциях можно использовать с 7 версии, никто не запрещает выполнить следующее, если у вас установлен ProjectCoin:
List<Integer> list = [3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5, 9];
Set<Integer> set = { 2, 7, 31, 127, 8191, 131071, 524287 };В 9 версии вы можете использовать нечто подобное без каких-либо предварительных подготовок:
List<Integer> piDigits = List.of(3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5, 9);
Set<Integer> primes = Set.of(2, 7, 31, 127, 8191, 131071, 524287);или
import static java.util.Map.*;
platonicSolids = ofEntries(entry(4, "tetrahedron"), entry(6, "cube"), ...);Так же было сказано несколько слов о generic Pair, а вернее об их отсутствии. Однако в 9 появился усовершенствованный костыль использования мапы в качестве пары:
Map.entry(lowest, highest)Ждем Project Valhalla.
2. Внедрение оператора Элвиса
На самом деле этот оператор реализован на Groovy на синтаксическом уровне, но если вы попробуете написать на джаве нечто подобное
Person person = JohnGold ?: DefaultPerson;компилятор предсказуемо ругнется. В девятке внедрили подобную логику, правда не на уровне синтаксиса. Ниже приведены два эквивалентных выражения на девятке и в уже привычном виде.
person = Objects.requireNonNullElse(JohnGold, DefaultPerson) //It will be work on Java 9
Optional<Person> maybePerson = JohnGold; // Familiar resolution
person = maybePerson.orElse(DefaultPerson);
3. Class Optional
Если кратко, этот класс для сбора not-null объектов: вместо того, чтобы проводить null-проверки, можно складывать объекты в данный контейнер, который автоматически будет отсеивать несуществующие объекты. Появился в Java 8 и вполне логично, что в новой версии появились улучшения для данного класса. Метод or интуитивно понятен: будет возвращен вызывающий объект, если он не нулевой, в противном случае вернется аргумент.
maybePerson = maybePerson.or(() ->
JohnGold); // Another OptionalСледующий метод выполняет заданное действие над значением, если оно присутствует, в противном случае будет выполнено некое дефолтное значение.
maybePerson.ifPresentOrElse(System.out::println, // Consumer
() -> Runtime.exec("rm -rf /home")); // RunnableЕсли значение присутствует, возвращает стрим только с этим значением, в противном случае стрим будет пустым.
Stream<T> stream()Возможность использовать flatMap для удаления нулевых результатов:
Stream<User> users = people.map(Person::name)
.flatMap(Optional::stream);4. Streams
Появился целый ряд методов API, из которых можно получить стримы: Scanner.tokens, Matcher.results, ServiceLoader.stream, LocalDate.datesUntil,
StackWalker.walk, ClassLoader.resources, Process.children/descendants,
Catalog.catalogs, DriverManager.drivers. В самих стримах тоже появились новые методы takeWhile, dropWhile, а также новые сборщики flatMapping, filtering.
5. IO, Regrexp
Тут все также масштабно. Появилась возможность считывать байты с поступающего потока
byte[] bytes = Files.newInputStream(path).readAllBytes();Перенаправлять байты с входящего потока на исходящий: InputStream.transferTo(OutputStream).
Появилась возможность разбить принимаемый классом Scanner объект на токены в виде отдельных стримов:
Stream<String> tokens = new Scanner(path).useDelimiter("\\s*,\\s*").tokens();Matcher.stream и Scanner.findAll выдают поток найденных результатов:
Pattern pattern = Pattern.compile("[^,]");
Stream<String> matches = pattern.match(str).stream().map(MatchResult::group);
matches = new Scanner(path).findAll(pattern).map(MatchResult::group);
Matcher.replaceFirst/replaceAll теперь могут принимать на вход функцию, согласно которой будет произведена перестановка:
String result = Pattern.compile("\\pL{4,}")
.matcher("Mary had a little lamb")
.replaceAll(m -> m.group().toUpperCase());
// Yields "MARY had a LITTLE LAMB"6. Обработка процессов
Тут появился целый интерфейс ProcessHandle, позволяющий контролировать нативные процессы. С его помощью можно мониторить жив ли процесс, информацию о нем, лист детей и прочие плюшки. Зачем он нужен, когда есть абстрактный класс Process, спросите вы. На самом деле ProcessHandle предоставляет гораздо больше возможностей, нежели Process. Последний в свою очередь также предоставляет доступ к IOE потокам, что сказывается на производительности.
7. Немного синтаксических изменений
Интерфейсы теперь могут иметь методы с модификаторами доступа private, private static и судя по всему в скором времени совсем перестанут быть интерфейсами. Нижнее подчеркивание _ больше не может являться именем переменной — гайки закручиваются. И, наконец, поддержка try-with-resources
void print (PrintWriter out, String[]lines){
try (out) { // Effectively final variable
for (String line : lines)
out.println(line.toLowerCase());
}
}
8. Старость
Появилось несколько деприкаций, куда же без этого. Классы Observable, Observer с новой версии будут считаться устаревшими, так же как и Object.finalize, Runtime.runFinalizersOnExit. Class.newInstance также теперь относят к Deprecated и аргументируют это тем, что он бросает проверяемые исключения конструктора без объявления их. Под ту же аннотацию попал весь Applet API, a также ряд модулей: java.activation, java.corba, java.transaction, java.xml.bind, java.xml.ws. Здесь были перечислены основные вещи, попавшие под аннотацию Deprecated и в презентацию Хорстмана, полный список всегда можно посмотреть у оракла.
9.Самая главная новость
System.getProperty("java.version")Теперь этот код вернет значение «9», а не «1.9.0.».
Также в Java 9 появилась модульность, которая вызвала бОльший шум, чем все вышеперечисленное. И это неудивительно, так как статистика показывает, что это модульность была наиболее ожидаемой фичей среди разработчиков

Были вопросы что это вообще такое, как это будет взаимодействовать с Maven. Половина доклада ушла на обзор OSGi, вторая половина на обзор Jigsaw и объяснение почему это круто, превосходит по всем параметрам предмет первой половины доклада и то, что Jigsaw незаслуженно скромно принимается обществом. Судить об успешности этого проекта мы действительно можем только от общества, а пока нам остается ждать глобального перехода на Java 9, который, как сказали сами докладчики, будет происходить ближайшие 2-3 года. А пока можно посмотреть на самые ожидаемые изменения в следующей версии джавы и слушать шутки о том, будет ли она называться Java 10 или Java X.

