Блоки текста — это многострочный строковый литерал, который устраняет необходимость в экранировании большинства специальных символов и автоматически делает переносы строки.
Это дальнейшая попытка исследований, начавшихся в JEP 326(необработанные строковые литералы, был отозван).
Цели JEP 355
- Упрощение написания Java кода избегая escape-последовательностей.
- Повышение читаемости кода.
То, чего JEP 355 точно не пытается достичь
- Это не попытка определить новый ссылочный тип, как
java.lang.String
. - Это не попытка переопределить строковой оператор "+".
- Блоки текста не поддерживают интерполяцию строк. Эта возможность может быть добавлена в последующих JEP'ах.
Мотивация
В Java для встраивания объектов XML, HTML, JSON и т.п. обычно требуется значительное редактирование с экранированием и конкатенацией строк. Фрагмент часто трудно читать и трудно поддерживать.
Соответственно, новый JEP улучшает как и удобочитаемость, так и добавляет возможность записи широкого класса программ на Java — используя строку состоящую из нескольких «строк» и без визуального беспорядка спец. символов. По сути, это двумерный блок текста, а не одномерная последовательность символов.
Синтаксис и описание
Блоки строк обрамляются
"""
и """
справа и слева. Содержание блока начинается с первого символа после """
и заканчивается на последнем символе перед """
. Тройные кавычки выбраны для того чтобы было понятно, что это строки текста, но чтобы можно было отличить их от обычного строкового литерала("..."
).Блоки могут содержать символы кавычек(
"
) напрямую, без слэша(\
). Можно использовать и \"
, но это не рекомендуется делать. Перенос строк делается автоматически. Использование \n разрешено, но не рекомендуется.
"""
line 1
line 2
line 3
"""
аналогично
"line 1\nline 2\nline 3\n"
или
"line 1\n" +
"line 2\n" +
"line 3\n"
Вот пример пустого блока текста:
String empty = """
""";
Вот плохая практика использования блоков текста:
String a = """""";
String b = """ """;
String c = """
";
String d = """
abc \ def
""";
Escape-последовательности в блоках текста
Escape-последовательности интерпретируются. Это означает, что разработчики могут писать escape-последовательности, например,
\n
внутри блоков.Примеры
HTML
String html = """
<html>
<body>
<p>Hello, world</p>
</body>
</html>
""";
String html = "<html>\n" +
" <body>\n" +
" <p>Hello, world</p>\n" +
" </body>\n" +
"</html>\n";
SQL
String query = """
SELECT `EMP_ID`, `LAST_NAME` FROM `EMPLOYEE_TB`
WHERE `CITY` = 'INDIANAPOLIS'
ORDER BY `EMP_ID`, `LAST_NAME`;
""";
String query = "SELECT `EMP_ID`, `LAST_NAME` FROM `EMPLOYEE_TB`\n" +
"WHERE `CITY` = 'INDIANAPOLIS'\n" +
"ORDER BY `EMP_ID`, `LAST_NAME`;\n";
Скрипт
ScriptEngine engine = new ScriptEngineManager().getEngineByName("js");
Object obj = engine.eval("""
function hello() {
print('"Hello, world"');
}
hello();
""");
ScriptEngine engine = new ScriptEngineManager().getEngineByName("js");
Object obj = engine.eval("function hello() {\n" +
" print('\"Hello, world\"');\n" +
"}\n" +
"\n" +
"hello();\n");
Комментарии (27)
vektory79
30.05.2019 14:09Интересно почему предидуший jep отменили. Выглядело неплохо…
CyberSoft
30.05.2019 17:59Автор не стал переводить раздел "Альтернативы", а зря. Там подробнее описывается опыт с Raw String Literals.
Я не переводчик, но вкратце: что-то у них там не зашло с разделителями строки в её содержимом. Они хотели сделать такой случай сразу неэкранируемым, но этот вариант "плохо бы поддерживался в будущем".
rmuskovets
30.05.2019 14:23А не слишком сильно похоже на Python? Там так само
maxzh83
30.05.2019 14:30+1Не только в Python «так само», в JVM языках Groovy и Scala также. А еще, судя по комментариям, в C# и Swift. Просто в случае с jvm-языками, можно посмотреть как реализовано технически.
Kalidratorma
30.05.2019 14:27С каждым релизом Java все больше становиться похожа на C#.
maxzh83
30.05.2019 14:32Вы рады этому или негодуете?
Kalidratorma
30.05.2019 14:45Рад. Это напоминает ситуацию с iOS и Android. Изначально один был скопирован с другого, теперь черпают друг у друга фичи. Конечный пользователь выигрывает в любом случае.
igormich88
30.05.2019 16:11+1На мой взгляд проблема именно в том что идёт копирование фич, а самостоятельное развитие языка крайне неспешно. Позиция догоняющего не очень хороша. В котлине например сейчас экспериментируют с инлайн классами которых вроде бы нет в других языках (не уверен на 100%)
Kalidratorma
30.05.2019 16:45Я считаю, что брать лучшие практики — хорошая стратегия развития. Описание inline class Котлина напоминает делегат.
Enverest
31.05.2019 13:10В котлине например сейчас экспериментируют с инлайн классами которых вроде бы нет в других языках (не уверен на 100%)
Похоже на value class в Скале.Yulaw
02.06.2019 08:39value class немного костыльные и не всегда работают, поэтому в скале работают над новым механизмом — opaque types
Будет скорее всего в 2.14, возможно в 2.13 под фича флагом
0xd34df00d
30.05.2019 22:27Escape-последовательности интерпретируются.
В регулярках по-прежнему придётся эскейпить
\
?
AnthonyDS
31.05.2019 10:06Остаётся её только сделать для Enterprise Edition, а для Standard Edition и Community закрыть лицензионным соглашением…
maxzh83
Не знаю чем «вдохновлялись» создатели блоков текста, но если Скалой (а там это реализовано точно также), то хочется, чтобы вдохновились еще сильнее и сделали уже и интерполяцию.
sshikov
Ага. Самое смешное, что и в груви это реализовано сто лет как, и тоже вполне удобно. И почему бы не срисовать с хороших примеров — не ясно.
DmitryAnatolich
Python?
KvanTTT
Еще в Swift так же.
igormich88
И в котлине, но там я думаю из скалы взято.
xxr1d3rx
В Dart тоже.
CyberSoft
Чем и откуда вдохновляются бывает написано в самих JEPах, причём с описанием того, как "это было бы в нашем случае": как поддерживать, на что влияет, как тестировать и т.д. и т.п. (это ответ и комментаторам ниже).
Про интерполяцию упомянуто, что это отдельная тема. Сначала запилят одно, потом итеративно другое. Собственно, и релизный цикл этому способствует.
Anton23 Автор
Да, там и описано. Точнее, там не написано чем вдохновлялись, там написано почему они не скопировали один в один из других языков:
0xd34df00d
А можно было бы вдохновиться ещё сильнее (но не скалой), сделать нормальные квазиквотеры и вынести что raw string literals, что интерполяцию строк, что ещё миллион вариантов применений, на уровень библиотек.
StrangerInTheKy
Anton23 Автор
Теперь? Уже вроде несколько лет как.