Java 21: String templates
В сентябре выходит java 21 (LTS) с интересной превью фичей —
String templates.
Есть две стратегии работы со строками:
🔸 Конкатенация — собираем строку по частям:
String str = "Hello, " + name + "!";
Сюда же относится
StringBuilder, метод
concat и тд.
🔸 Интерполяция — замена переменных внутри шаблона:
String name = "Jake";
String str = "Hello, ${name}!";
В чистом виде в java такого нет. В
Formatter и
MessageFormat вместо переменных какие-то %s и %d, а переменные стоят отдельно:
String.format("%d plus %d equals %d", x, y, x + y);
Для сравнения, как это выглядит в Kotlin:
"$x plus $y equals ${x + y}"
Так вот, в java 21 появится интерполяция!
В начале строки нужно добавить
STR., а переменные поместить в
\{}
int x = 10, y = 20;
String str = STR."\{x} + \{y} = \{x + y}";
// "10 + 20 = 30"
Хорошо работает вместе с текстовыми блоками (многострочные строки в тройных кавычках):
String name = "Joan";
String phone = "555-123";
String json = STR."""
{
"name": "\{name}",
"phone":"\{phone}",
}
""";
Внутри можно вызывать методы и писать блоки кода:
String time = STR."The time is \{
DateTimeFormatter
.ofPattern("HH:mm:ss")
.format(LocalTime.now())
} right now";
//"The time is 09:01:45 right now"
Читаемость текста снижается, но если очень хочется — почему нет.
❓ Зачем нужен префикс STR? Почему нельзя просто добавить новый функционал в строки?
Здесь 2 причины:
1️⃣ Для обратной совместимости
На джаве написано много кода, и наверняка какие-то строки содержат блоки \{}. Будет обидно, если этот код перестанет компилироваться. Поэтому строки для интерполяции нужно явно обозначить
2️⃣ Может быть не только STR😱
Здесь открывается портал в другой мир. По задумке авторов темплейты могут подставлять переменные, валидировать данные и делать преобразования. Например, так:
JSONObject json = JSON."{ id: \{id}}";
или даже так:
ResultSet rs = DB."SELECT * FROM Person WHERE name = \{name}";
Для запросов в БД это, наверное, слишком, а вот для работы с JSON выглядит очень удобно.
Но рано радоваться🙂 Из коробки этого не будет, только набор классов для кастомизации. Будем надеяться, что авторы библиотек возьмут фичу на вооружение.
❓ Как это работает? Выглядит как магия!
В JDK появится статическое поле
StringProcessor STR, а строка
String str = STR."\{name}!"; во время компиляции превратится в
StringTemplate template = new StringTemplate(паттерн, параметры);
String str = STR.process(template);
Cинтаксический сахарок и никакого волшебства✨