Найти в Дзене

Новая Версия Java 13

Мы уже успели привыкнуть к тому, что новый релиз JDK появляется раз в полгода. Пока что такой подход себя оправдал, а переживания некоторых разработчиков, дескать они не будут поспевать за обновлениями, оказались напрасными: полугодовых изменений немного и они не столь глобальны, как раньше. Ну а начинающие программисты могут и вовсе не заметить новшества.

Тем не менее, будущим разработчикам ПО лучше быть в курсе нововведений. В этой статье мы традиционно опишем принятые предложения по расширению (JEP). Java 13 включает в себя только пять JEP’ов и 76 новых элементов базовой библиотеки (из которых почти половина — простые дополнения к пакету java.io).

JEP 355: Text Blocks(Preview)

Начнем с изменения синтаксиса языка. Самое значительное из них — это текстовые блоки. Они позволяют избегать экранирования символов и умеют форматировать строки. Возможно, вы помните, что в JDK 12 так и не появилась ожидаемая фича Raw String Literals (JEP 326) для работы со строковыми литералами. В Java 13 ей на смену пришёл JEP 355 с его текстовыми блоками. Вы, вероятнее всего, помните, что в Java строка обёрнута в двойные кавычки. Это хорошо, но проблема в том, что строка не может занимать больше одной линии исходного файла (чтобы не путать с Java-строкой, здесь будем называть строку файла “линией”). Что ж, пойдём в обход и используем, например, символ \n, если требуется разрыв, или конкатенацию многострочных выражений. Не очень-то красиво получается! Особенно громоздко выглядят текстовые литералы со встроенными фрагментами HTML, XML, SQL или JSON. Все эти экранирования, конкатенации, ручное редактирование делает код неудобным для написания и трудночитаемым. Текстовые блоки пытаются эту проблему решить. Они начинаются с тройных двойных кавычек и заканчиваются ими же (знаю, звучит не очень). Всё, что находится между кавычками, интерпретируется как часть строки, включая переводы на новую линию. Текстовые блоки можно использовать точно так же, как стандартные текстовые литералы, Java скомпилирует код одинаково. Открывающие кавычки должны сопровождаться ограничителем строки; текстовые блоки нельзя использовать в одну линию, так что код

String smallBlock = """Only one line""";

приведёт к следующим ошибкам:

TextBlock.java:3: error: illegal text block open delimiter sequence, missing line terminator
String smallBlock = """Text Block"""; ^
TextBlock.java:3: error: illegal text block open delimiter sequence, missing line terminator
String smallBlock = """Text Block""";

Простой HTML-фрагмент теперь можно написать так:

String htmlBlock = """
<html>
<body>
<p>CodeGym Web page</p>
</body>
<html>
""";

Упомянём несколько тонкостей, о которых лучше знать при использовании текстовых блоков. Расположение закрывающих кавычек оказывается важным: оно определяет, как обрабатывается случайный пробел. В приведенном выше примере закрывающие кавычки выровнены с отступом текста HTML. В этом случае компилятор удалит пробелы отступа, и в результате мы получим такую строку:

<html>
<body>
<p>My web page</p>
</body>
</html>

Обратите внимание: такая строка будет содержать новую линию в конце строки. Если она не нужна, закрывающие кавычки “”” можно поставить непосредственно после тега </ html>.

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

В версию JDK 13 текстовые блоки попали в качестве превью-фичи. Это значит, что они пока не включены в соответствующую спецификацию языка Java. То есть непонятно, станет ли эта фича постоянной частью языка или она тут только гость. В настоящее время разработчики могут протестировать фичу и высказать мнение о ней. От него и будет зависеть судьба текстовых блоков: фичу могут улучшить, а если она не понравится — то и вовсе удалить. Если вы хотите опробовать текстовые блоки на практике, помните, что превью-фичи нужно явно включать для компиляции и выполнения.

В классе String есть три новых метода, которые дополняют это изменение языка:

  • formatted(): форматирует строку, используя саму строку в качестве строки формата. Эквивалентен вызову format(this, args)
  • stripIndent(): удаляет случайные пробелы из строки. Это полезно, если вы читаете многострочные строки и хотите применить такое же исключение случайных пробелов, как и в случае явного объявления.
  • translateEscapes(): возвращает строку с escape-последовательностями (например, \ r), переведенными в соответствующее значение Unicode.

Любопытно, что эти методы только появились, но уже помечены как deprecated... такое положение вещей наводит на мысль, что их могут удалить в будущей версии JDK. Это кажется несколько эксцентричным — добавлять новый метод и сразу же отказываться от него. Однако нужно учесть, что эти методы связаны с превью-фичей, которая может быть изменена или удалена. Возможно, введение аннотации @PreviewFeature помогло бы с подобными ситуациями, но пока такая она не входит в JDK (хотя с высокой долей вероятности она появится в JDK 14).