Эта статья написанаyanglbmeОригинал, впервые опубликованный в публичном аккаунте"Сообщество открытого исходного кода Doocs", несанкционированное воспроизведение запрещено.
«Вы продолжаете обновлять каждые шесть месяцев, а я продолжаю использовать Java 7/8».
Это может быть текущая ситуация многих друзей. Если честно, Ява"Каждые полгода выходит новая версия«Ритм действительно немного ускорился. Но, несмотря ни на что, новые технологии и новые функции по-прежнему заслуживают изучения.
В Java 13 с текстовыми блоками мы можем легко использовать многострочные строки. Нам больше не нужно экранировать специальные символы в строках или использовать строки, которые охватывают несколько строк.+
Оператор конкатенации, значительно улучшающий читабельность кода. В этой статье я расскажу об особенностях и сценариях использования текстовых блоков Java 13, давайте посмотрим.
Что такое текстовый блок?
Тип данных String, вероятно, является одним из наиболее часто используемых типов Java-разработчиками. Он может хранить все, от нескольких символов до нескольких строк на любом языке. Однако эта гибкость также затрудняет чтение или изменение некоторых значений String. Например, с кавычками, escape-символами или строками, занимающими несколько строк.
Текстовые блоки — это элемент Java 13.Функция предварительного просмотра, мы можем использовать текстовые блоки, чтобы легко определять многострочные строки без добавления операторов конкатенации и escape-символов. Кроме того, мы можем контролировать форматирование строковых значений.
Давайте посмотрим на следующий фрагмент HTML:
String html = """
<HTML>
<BODY>
<H1>"Java 13 is here!"</H1>
</BODY>
</HTML>""";
Уведомление, три двойных кавычки"""
Определяет начало и конец блока соответственно. Взгляните, как это было определено до Java 13:
String html =
"<HTML>\n\t<BODY>\n\t\t<H1>\"Java 13 is here!\"</H1> \n\t</BODY>\n</HTML>\n";
Или, что более типично:
String html = "<HTML>" +
"\n\t" + "<BODY>" +
"\n\t\t" + "<H1>\"Java 13 is here!\"</H1>" +
"\n\t" + "</BODY>" +
"\n" + "</HTML>";
Вышеупомянутые два способа письма гораздо менее читаемы, чем текстовые блоки.
синтаксис текстового блока
Как упоминалось ранее, Java 13 использует три двойных кавычки."""
Определяет текстовые блоки как начальный и конечный разделители.начальный разделительпозже можетза которым следует ноль или более пробелова такжетерминатор строки;Аналогичного правила для терминаторов нет..
Такие грамматические правила, приведенные в следующем примере, на самом деленеверный текстовый блок,потому что они не содержат терминатора строки после открывающего разделителя:
String multilineValue1 = """ """;
String multilineValue2 = """""";
Это просто функция предварительного просмотра
Текстовые блоки были выпущены в качестве функции предварительного просмотра в Java 13, но функция предварительного просмотра не означает, что это неполная или недоработанная функция. По сути, это означает, что даже если эта функция будет доступна разработчикам, она может измениться в будущих версиях Java.
На самом деле для этого есть причина. С периодичностью «новый выпуск каждые шесть месяцев» разработчики могут быстро получить доступ к новым функциям языка. Однако, прежде чем постоянно добавлять языковые функции в Java, команда Java оценивает то, что говорят об этом разработчики. В зависимости от отзывов функция предварительного просмотра может быть усовершенствована перед добавлением в Java SE или полностью удалена.
Чтобы испытать функции языка предварительного просмотра, нам нужно включить их вручную с помощью компиляции и среды выполнения. Это гарантирует, что мы случайно не воспользуемся функцией предварительного просмотра. Использование текстовых блоковкомпилироватьисходный файл, пожалуйста, используйте--enable-preview
а также-release 13
опции. В следующем примере показано, как использовать командную строку длякомпилироватьисходные файлы, например, дляJava13.java
документ:
javac --enable-preview --release 13 Java13.java
Чтобы улучшить предварительный просмотр возможных изменений, при выполнении предыдущей команды мы получим предупреждение компилятора, как показано ниже.
Note: Java13.java uses preview language features.
Note: Recompile with Xlint:preview for details.
Чтобы выполнить класс Java13, нам нужно использовать--enable-preview
Опции:
java --enable-preview Java13
Далее рассмотрим реализацию текстового блока.
Все еще строковый тип данных
И традиционные строки, и текстовые блоки компилируются в один и тот же тип:String
. Файлы классов байт-кода не могут отличить, получено ли строковое значение из традиционной строки или из блока текста. Это означает, что значения текстового блока хранятся в пуле строк.
Рассмотрим следующий код, где, как вы думаете, переменнаяtraditonalString
а такжеtextBlockString
относятся к одному и тому же экземпляру String?
String traditionalString = "Java";
String textBlockString = """
Java""";
System.out.println(traditionalString == textBlockString);
Ответ «да», потому что их содержание абсолютно одинаково, поэтому приведенный выше код выведетtrue
.
В начале статьи я говорил об утомительности использования традиционного String для обработки многострочных строк, далее давайте посмотрим, насколько текстовые блоки удобны в Java 13?
Легко обрабатывать многострочные значения
определить JSON
Разработчики часто работают с многострочными строковыми значениями, такими как JSON, HTML, XML или данные регулярных выражений (regex). С текстовыми блоками способ работы с многострочными значениями JSON прост.
String json = """
{
"name": "web",
"version": "1.0.0",
"dependencies": "AppA"
}
""";
Без escape-символов и операторов конкатенации код визуально интуитивно понятен, поэтому мы можем легко редактировать и изменять значение JSON. Не верю? Сравните это с использованием традиционной строки для определения значений JSON:
String json =
"{" +
"\"name\": \"web\"," +
"\"version\": \"1.0.0\"," +
"\"dependencies\": \"AppA\" +
"}";
Определить SQL
Иногда нам нужно хранить операторы SQL-запросов в виде строк. Предположим, мы храним многострочный SQL-запрос с использованием переменной String следующим образом (для Java 12 или более ранней версии):
String query =
"SELECT name, age" +
"FROM EMP" +
"WHERE name = \'John\' +
"AND age > 20";
Вам кажется, что в этом нет ничего плохого? ФактическиЧто-то не так, это недопустимый SQL-запрос. Из-за отсутствия пробелов в конце каждой строки этот запрос будет интерпретироваться следующим образом:
SELECT name, ageFROM EMPWHERE name = 'John'AND age > 20
Подобных проблем можно избежать, используя текстовые блоки:
String query = """
SELECT name, age
FROM EMP
WHERE name = 'John'
AND age > 20
""";
определить регулярные выражения
Регулярные выражения часто содержат много специальных символов. До Java 13, когда мы писали регулярное выражение в виде строки, нам часто приходилось экранировать некоторые специальные символы, что затрудняло нам написание, чтение или понимание этих выражений.
Это регулярное выражение, которое сохраняется перед текстовым блоком[0-9]{3}\-[0-9]{4}
Пример:
String java12OrBeforeRegex = "[0-9]{3}\\t-[0-9]{4}";
С текстовыми блоками мы можем определить одно и то же регулярное выражение следующим образом:
String java13Regex = """
[0-9]{3}\t-[0-9]{4}""";
Экранирующие символы в текстовых блоках
Мы можем добавлять различные escape-символы к блокам текста так же, как мы добавляем их к строке. Например, это можно сделать, поместив значение в несколько строк или используя escape-символы, такие как\n
), чтобы включить новые строки в текстовый блок. В следующем кодеI'm
а такжеhappy
будет на двух отдельных линиях.
String html = """
<HTML>
<BODY>
<H1>I'm \nhappy</H1>
</BODY>
</HTML>""";
Как обрабатываются пробелы и отступы?
Ключевой вопросКак бороться с текстовым блоком, включенным в пробел. На самом деле, это хорошо обрабатывается компилятором. В текстовом блоке, в любой строкеКрайний левый непробельный символиликрайний левый разделительОпределяет, где начинается строка.
На изображении ниже мы можем видетьgetHTML()
Метод возвращает значение типа String, крайний левый непробельный символ которого начинается с<
(<HTML>
середина<
)начало,Символ выровнен с закрывающим разделителем.
Код на рисунке выше фактически возвращает строку, показанную на рисунке ниже (первая строка<HTML>
и последняя строка</HTML>
без начальных пробелов):
Чтобы пометить пробельные символы в начале строки по мере необходимости (т.е. зарезервировано<HTML>
пробел слева), нам нужно переместить разделитель или любой непробельный символ влево.
Например, мы закроем разделитель"""
Переместиться на 8 делений влево:
Измененный код вернет значение String, показанное на изображении ниже, и вы можете видеть, что в каждой строке добавлено 8 начальных пробелов, а также дополнительные пробелы для пользовательского отступа.
По умолчанию текстовые блоки удаляют пробелы в конце каждой строки. Если вам нужно добавить их, вы можете использовать восьмеричные escape-символы.\040
(в ASCII пробелов 32), чтобы принудительно включить их.
Вот пример добавления пробела в конец второй строки текстового блока:
String campaign = """
Don't leave home without -
money &\040
carry bag.
Reduce | Reuse
""";
Обратите внимание, что если базовое пространство содержит вкладки
\t
, он не расширяется, а считается как один пробел.
Объединение текстовых блоков
Текстовые блоки можно передавать с традиционными строковыми значениями.+
подключение, следующий пример:
String concatenate() {
return """
Items to avoid -
Single
Use
Plastics
"""
+
"Let's pledge to find alternatives";
}
Этот метод предусмотрен, потому что нам иногда нужно вставить значение переменной в строку:
String concatenate(Object obj) {
return """
Items to avoid -
Single
Use
"""
+ obj + """
Let's pledge to find
alternatives""";
}
Текстовые блоки можно использовать как строки, преимущество в том, что мы можем использовать методы String в текстовом блоке. Например, мы можем использоватьString.replace()
метод без какой-либо специальной обработки:
String concatenateReplace(Object obj) {
return """
Items to avoid -
Single
Use
$type
Let's pledge to find
alternatives""".replace("$type", obj.toString());
}
Точно так же мы можем использовать метод format() или любой другой метод String.
Суммировать
Эта статья достаточно подробна для описания текстовых блоков Java 13. Текстовые блоки могут помочь нам, разработчикам, легко обрабатывать многострочные строковые значения. Имейте в виду, что текстовые блоки в настоящее время являются только функцией предварительного просмотра и могут измениться в любое время. Но даже с этой возможностью текущего текстового блока это, безусловно, сэкономит нам много работы по кодированию.