Java 11

var (в лямбде)
Отныне и во веки веков мы можем указать типы лямбда-параметров или пропустить их при написании лямбда-выражения (неявно типизированных лямбда-выражений):
Function<String, String> append = (var string) -> string + " Text";
String appendedString = append.apply("Some");
System.out.println(appendedString);
Также можно добавлять аннотации к лямбда-параметрам без необходимости писать полное имя типа переменной:
Function<String, String> append = (@NonNull var string) -> string + " Text";
Z (ZGC)
ZGC — это новый сборщик мусора, который не работает. Он выделяет новую память, но никогда не перезапускает ее. ZGC обещает управлять большими объемами памяти с высокой пропускной способностью и коротким временем паузы (ZGC доступен только на 64-битных платформах). Эталонная окраска — ZGC использует 64-битные указатели с техникой, называемой окрашиванием указателей. Цветные указатели хранят дополнительную информацию об объектах в куче. Когда память становится фрагментированной, это помогает избежать снижения производительности, когда GC необходимо найти место для нового распределения. Сборка мусора с помощью ZGC состоит из таких этапов:- остановки мира: мы ищем отправные точки для достижения объектов в куче (например, локальных переменных или статических полей);
- пересечение граф объектов, начиная с корневых ссылок. Мы отмечаем каждый объект, который достигаем (ZGC ходит по графу объектов и исследует цветные указатели, отмечая доступные объекты);
- обработки некоторых крайних случаев, например, слабых ссылок;
- перемещение живых объектов, освобождая большие участки кучи, чтобы ускорить распределение.
- когда начинается фаза перемещения, ZGC разделяет кучу на страницы и работает по одной странице за раз;
- ZGC заканчивает движение любых корней, и происходит остальная часть перемещения.
- An Introduction to ZGC: A Scalable and Experimental Low-Latency JVM Garbage Collector
- Самодельный сборщик мусора для Open JDK
- Java's new Z Garbage Collector (ZGC) is very exciting
Epsilon GC
Эпсилон — это сборщик мусора, который обрабатывает выделение памяти, но не реализует какой-либо реальный механизм ее восстановления памяти. Как только доступная куча Java будет исчерпана, JVM закроется. То есть, если в бесконечном массиве запустить создание объекта без привязки к ссылке с данным сборщиком мусора, приложение упадёт с OutOfMemoryError (а если с любым другим нет, так как он будет подчищать объекты без ссылок). Зачем он нужен? А вот зачем:- Тестирование производительности.
- Тестирование давления памяти.
- Тестирование интерфейса VM.
- Чрезвычайно недолгая работа.
- Улучшения латентности последней капли.
- Улучшения пропускной способности последней капли.
- Новый GC Epsilon. У джавы может не быть сборки мусора. Шок. Сенсация
- An Introduction to Epsilon GC: A No-Op Experimental Garbage Collector
ByteArrayOutputStream
получил методvoid writeBytes(byte [])
, записывающий все байты из аргумента вOutputStream
.FileReader
иFileWriter
получили новые конструкторы, позволяющие указывать Charset.Path
отхватил два новых метода,of(String, String [])
возвращаетPath
из строкового аргумента пути или последовательности строк, которые при объединении образуют строку пути иof(URI)
: возвращает Path из URI.Pattern
— получил методasMatchPredicate()
, который проверяет, соответствует ли заданная строка ввода, заданному шаблону (позволяет ли создать предикат по регулярному выражению, чтобы можно было, например, фильтровать данные в stream).String
отхватил много полезных методов, таких как:String strip()
: вернёт нам строку, которая является этой строкой, при этом удаляются все пробелы в начале и в конце строки (аналог trim(), но по-другому определяет пробелы);String stripLeading()
: вернёт нам строку, которая является этой строкой, при этом удаляются все пробелы в начале строки;String stripTrailing()
: вернёт нам строку, которая является этой строкой, при этом удаляются все пробелы в конце строки;Stream lines()
: вернёт намStream
изString
, извлеченных из этой строки, поделенных разделителями строк;String repeat(int)
: вернёт нам строку, которая представляет собой конкатенацию этой строки, повторяющееся количество раз.boolean isBlank()
: вернёт нам true, если строка пуста или содержит только пробелы, иначе false.
Thread
— были удалены методы destroy() и stop(Throwable).Files
получил ряд новых методов:String readString(Path)
: читает все данные из файла в строку, при этом декодируя из байт в символы с использованием кодировки UTF-8;String readString(Path, Charset)
: так же, как и в методе выше, с разницей в том, что декодирование из байт в символы происходит с использованием указанной Charset;Path writeString (Path, CharSequence, OpenOption [])
: записывает последовательность символов в файл. Символы кодируются в байты, используя кодировку UTF-8;Path writeString(Path, CharSequence,Charset, OpenOption [])
: такой же метод, что и выше, только символы кодируются в байты, используя кодировку, указанную в Charset.
Java 12
Проходит полгода, и мы видим следующую ступень эволюции Java. Значит, пора доставать лопатку знаний и копать.
Update G1
Для G1 были внесены такие улучшения:Возврат неиспользуемой выделенной памяти
В Java heap memory есть такое понятие как неиспользуемая память (или по-другому — неактивная). В Java 12 решили пофиксить эту проблему, теперь:
- G1 возвращает память из кучи в полном GC или во время параллельного цикла; G1 старается предотвратить полный GC и запускает параллельный цикл, исходя из распределения кучи. Придется принуждать G1 к возвращению памяти из кучи.
Данное улучшение фокусируется на быстродействии за счет автоматического возврата памяти из кучи в ОС, когда G1 не используется.
Прерывание смешанных коллекций, когда время паузы превышено
G1 использует механизм анализа для выбора объема работы, необходимого для сбора мусора. Он собирает живые объекты без остановки после определения набора и запуска очистки. Это приводит к тому, что сборщик мусора превышает целевое значение времени паузы. Собственно, такую проблему и решает улучшение, так как если время выполнения следующего шага выходит за рамки разумного, этот шаг можно прервать.
Microbenchmark
В Java 12 ввели тесты микробенчмаркинга, чтобы производительность JVM легко тестировалась с помощью уже существующих тестов. Это было бы очень полезно для всех, кто хочет работать над самой JVM. Добавляемые тесты создаются с использованием Java Microbenchmark Harness (JMH). Эти тесты позволяют проводить непрерывное тестирование производительности на JVM. JEP 230 предлагает ввести около 100 тестов, причем новые тесты вводятся по мере выпуска новых версий Java. Вот пример добавляемых тестов.Shenandoah
Это алгоритм сборки мусора (GC), цель которого — гарантировать низкое время отклика (нижний предел — 10-500 мс). Это уменьшает время паузы GC при выполнении работы по очищению одновременно с работающими потоками Java. В Shenandoah время паузы не зависит от размера кучи. Это означает, что время паузы будет одинаковым независимо от размера вашей кучи. Это экспериментальная функция, которая не включена в стандартную (Oracle) сборку OpenJDK.Improve Switch
В Java 12 улучшены выражения Switch для сопоставления с образцом. Был введен, новый синтаксис L →. Вот список ключевых моментов нового switch:- Новый синтаксис устраняет необходимость в операторе break для предотвращения ошибок.
- Выражения переключателя больше не проваливаются.
- Кроме того, мы можем определить несколько констант в одной метке.
- default регистр теперь обязателен в выражениях переключателей.
- break используется в выражениях Switch для возврата значений из самого регистра (по сути switch может возвращать значения).
var result = switch (someDay) {
case "M", "W", "F" -> "MWF";
case "T", "TH", "S" -> "TTS";
default -> {
if(someDay.isEmpty())
break "Please insert a valid day.";
else
break "Looks like a Sunday.";
}
};
Definitive Guide To Switch Expressions In Java 13
Другие нововведения:
String:
transform(Function f)
— применяет предоставленную функцию к строке. Результат может не быть строкой.
indent(int x)
— добавляет x пробелов в строку. Если параметр отрицателен, то это количество начальных пробелов будет удалено(если это возможно).Files
— отхватил такой метод какmismatch()
, который, в свою очередь, находит и возвращает позицию первого несовпадающего байта в содержимом двух файлов или -1L, если нет несоответствия.Появился новый класс —
CompactNumberFormat
, для форматирования десятичного числа в компактной форме. Пример такой компактной формы — 1M вместо 1000000. Таким образом, требуется всего лишь два два вместо девяти символов.Существует также новый
enum
,NumberFormatStyle
, у которого есть два значения — LONG и SHORT.InputStream
получил метод —skipNBytes(long n)
: пропустить n-ое количество байтов из входного потока.
- Java 12 уже здесь: что нового?
- Что нового в Java 12
- Что нового в Java 12 (из блога записки ведьмака-программиста)
Java 13
Мир не стоит на месте, шевелится, развивается, как и Java — Java 13.
Text block
Java всегда немного страдала от определения строк. Если нам нужно определить строку с пробелом, перенос строки, кавычку или ещё что-то, это вызывало некоторые трудности, так приходилось использовать специальные символы: например, \n для переноса строки, или экранировать некоторые из самой строки. Это существенно снижает читаемость кода, и занимает лишнее время при написании такой строки. Эта становится особо заметным при написании строк, отображающих JSON, XML, HTML и т.д. В итоге если мы хотим написать небольшой Json, это будет выглядеть как-то так:
String JSON_STRING = "{\r\n" + "\"name\" : \"someName\",\r\n" + "\"site\" : \"https://www.someSite.com/\"\r\n" + "}";
И тут на сцену выходит Java 13 и предлагает нам свое решение в виде тройных двойных кавычек до и после текста (которые и обозвали текстовыми блоками).
Давайте рассмотрим предыдущий пример json с использованием данного нововведения:
String TEXT_BLOCK_JSON = """
{
"name" : "someName",
"site" : "https://www.someSite.com/"
}
""";
В разы проще и наглядней, не правда ли?
Также было в String
было добавлено три новых метода, соответственно, для управления данными блоками:
stripIndent()
: удаляет случайные пробелы из строки. Это полезно, если вы читаете многострочные строки и хотите применить такое же исключение случайных пробелов, как это происходит с явным объявлением (по сути имитирует компилятор для удаления случайных пробелов);formatted(Object... args )
: аналогformat(String format, Object... arg)
, но для текстовых блоков;translateEscapes()
: возвращает строку с escape-последовательностями (например, \ r), переведенными в соответствующее значение Unicode.
Improve Switch
Выражения-переключатели были введены в Java 12, а 13 уточняет их. В 12 вы определяете возвращаемые значения с помощью break. В 13 возвращаемое значение заменили на yield. Теперь выражение со switch, которое было у нас в разделе Java 12, можно переписать как:
var result = switch (someDay) {
case "M", "W", "F" -> "MWF";
case "T", "TH", "S" -> "TTS";
default -> {
if(someDay.isEmpty())
yield "Please insert a valid day.";
else
yield "Looks like a Sunday.";
}
};
Хотя нам программистам, уже знакомым с Java, было нормально принять break, но, тем не менее, это было довольно странно. Что break true пытается мне сказать? Новое (условно новое) ключевое слово yield более понятно, и в будущем оно может появиться в других местах, где возвращаются значения.
Кому глубоко интересна данная тема, рекомендую ознакомиться с данными материалами:
Dynamic CDS Archives
CDS — Class-Data Sharing. Позволяет упаковывать набор часто используемых классов в архив, который позже может быть загружен несколькими экземплярами JVM. Зачем нам это? Дело в том, что в процессе загрузки классов JVM делает довольно много ресурсозатратных действий, таких как чтение классов, сохранение их во внутренних структурах, проверка правильности прочитанных классов, поиск и загрузка зависимых классов и т. д., и лишь после всего этого классы готовы к работе. Понятное дело, попусту тратится большое количество ресурсов, ведь экземпляры JVM часто могут загружать одни и те же классы. Например String, LinckedList, Integer. Ну или же классы одного и того же приложения, а все это — ресурсы. Если бы мы выполнили все необходимые действия лишь один раз и после поместили переработанные классы в архив, который может быть подгружен в память нескольких JVM, это могло бы существенно сэкономить место в памяти и сократить время запуска приложения. Собственно, CDS дает возможность создать именно такой архив. Java 9 позволяла добавлять в архив только системные классы. Java 10 — включать в архив классы приложения. Создание такого архива состоит из:- создания списка классов, загружаемых приложением;
- создания так необходимого нам архива с найденными классами.
Update Socket API
API Socket (java.net.Socket и java.net.ServerSocket) — по сути неотъемлемая часть Java с момента ее появления, но при этом сокеты ни разу не апдейтили за последний двадцаток лет. Написанные на C и Java, они были очень и очень громоздкими и сложными в обслуживании. Но Java 13 решила внести свои коррективы в это всё дело и заменила базовую реализацию. Теперь вместо PlainSocketImpl интерфейс провайдера заменяется на NioSocketImpl. Эта новая кодированная реализация основана на той же внутренней инфраструктуре, что и java.nio. По сути класс использует механизм буферного кэша и блокировки java.util.concurrent (которые являются сегментными), а не синхронизированные методы. Он больше не требует нативного кода, тем самым упрощая портирование на разные платформы. Всё же, у нас есть способ вернуться к использованию PlainSocketImpl, но отныне по дефолту используется NioSocketImpl.Memory Return for ZGC
Как мы помним, Z сборщик мусора ввели в Java 11 как механизм сборки мусора с малой задержкой, чтобы GC пауза никогда не превышала 10 мс. Но при этом, в отличие от остальных виртуальных GC HotSpot, таких как Shenandoah и G1, он мог возвращать неиспользованную динамическую память в ОС. Данная модификация добавляет эту возможность J в ZGC. Соответственно, мы получаем уменьшенный объем памяти вместе с улучшением производительности, и ZGC теперь возвращает не зафиксированную память операционной системе по умолчанию, пока не будет достигнут указанный минимальный размер кучи. И ещё: у ZGC теперь есть максимальный поддерживаемый размер кучи 16 ТБ. Раньше 4ТБ было пределом. Другие нововведения:javax.security
— добавлено свойствоjdk.sasl.disabledMechanisms
для отключения механизмов SASL.java.nio
— добавлен методFileSystems.newFileSystem (Path, Map <String,?>)
— соответственно, для создания нового файла.- Классы
java.nio
теперь имеют абсолютные (в отличие от относительных)get
иset
-методы. Они, как и базовый абстрактный классBuffer
, включают методslice()
для извлечения части буфера. - В
javax.xml.parsers
добавлены методы для создания экземпляров фабрик DOM и SAX (с поддержкой пространств имен). - Поддержка Unicode обновлена до версии 12.1.
- Java 13: новые возможности
- Всё о Java 13: погружение в мир обновлений
- 81 New Features and APIs in JDK 13
Итоги
Мы могли бы и пройтись по заявленным нововведениям в Java 14, но так как она довольно-таки скоро увидит свет — выпуск JDK 14 запланирован на 17 марта 2020 года, лучше всего будет провести отдельный, полноценный обзор на неё уже непосредственно после выхода. Еще хотелось бы обратить внимание на то, что в других языках программирования с большими перерывами между выпусками, как например в Python 2–3, нет совместимости: то есть если код написан на Python 2, нужно будет изрядно попотеть, переводя его на 3. Java — особенная в этом отношении, поскольку она чрезвычайно обратно совместима. Это означает, что ваша программа на Java 5 или 8 гарантированно будет работать с виртуальной машиной Java 8-13 — с некоторыми исключениями, о которых вам сейчас не нужно беспокоиться. Понятное дело, что это не работает наоборот: например, если ваше приложение юзает функции Java 13, которые просто недоступны в Java 8 JVM. На этом у меня сегодня всё, тем кто дочитал до этого места — респект))
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ