W3docs

Текстовые блоки Java

Пишите многострочные строковые литералы в Java с помощью текстовых блоков (тройные кавычки).

Текстовый блок — это многострочный строковый литерал, избавляющий от лишних экранирований символов новой строки и конкатенации. Введённый как предварительная функция в Java 13 и ставший постоянным в Java 15, он позволяет вставлять HTML, JSON, SQL или любой форматированный текст прямо в исходный код — так, чтобы он читался в своём естественном виде.

До появления текстовых блоков несколько строк встроенной разметки превращались в нагромождение экранирований \n и операторов +. Текстовый блок открывается тремя двойными кавычками (""") с последующим переводом строки, и всё вплоть до закрывающего """ становится строкой — с интеллектуальной обработкой ведущих пробелов.

Синтаксис тройных кавычек

Текстовый блок начинается с """ и символа конца строки. Содержимое начинается со следующей строки; открывающий разделитель не может находиться в одной строке с текстом. Блок завершается ещё одним """.

// Old way: escapes and concatenation
String json = "{\n" +
              "  \"name\": \"Ada\"\n" +
              "}";

// Text block: paste it as-is
String block = """
    {
      "name": "Ada"
    }
    """;
Внимание
The most common compile error is writing content on the opening line, e.g. String s = """{. The opening """ must be followed immediately by a line terminator — only the closing """ may share its line with text.

Оба варианта дают практически идентичные строки, но текстовый блок читается с первого взгляда, а встроенные двойные кавычки не требуют экранирования. Текстовый блок — это String, как и любой другой, отдельного типа не существует, поэтому все методы String работают с ним, и текстовый блок по-прежнему неизменяем после создания.

Случайные и существенные пробелы

Компилятор разделяет случайные пробелы (отступы, добавленные только для того, чтобы исходный код выглядел аккуратно) и существенные пробелы (отступы, которые вы действительно хотите видеть в значении строки). Он находит строку с наименьшим количеством ведущих пробелов — включая строку с закрывающим """ — и удаляет это общее количество из каждой строки.

String html = """
        <p>Hi</p>
    """;
// The closing """ is indented 4 spaces, the <p> 8 spaces.
// Common minimum is 4, so the result keeps 4 leading spaces: "    <p>Hi</p>\n"

Перемещение закрывающего разделителя меняет количество удаляемых символов. Если поместить """ в самом начале строки, отступы не удаляются; если поставить его под самой глубокой строкой — удаляются все. Это даёт точный контроль без ручного подсчёта пробелов.

Экранирование и завершающий перевод строки

Текстовые блоки поддерживают обычные управляющие последовательности, а также две, существующие только для них:

ЭкранированиеЭффект
\n, \t, \"Стандартные управляющие последовательности, по-прежнему действительны
\ (в конце строки)Продолжение строки — подавляет следующий символ новой строки
\sОдиночный пробел, который никогда не удаляется как случайный пробел

Текстовый блок, содержимое которого заканчивается на отдельной строке, включает завершающий символ новой строки; размещение закрывающего """ на той же строке, что и последний текст, исключает его.

String withNewline = """
    last line
    """;          // ends with "\n"

String noNewline = """
    last line""";  // no trailing newline

Распространённые случаи использования

Текстовые блоки особенно удобны там, где в коде присутствует форматированный многострочный текст:

// SQL kept readable instead of one long escaped string
String query = """
    SELECT id, name, price
    FROM products
    WHERE price < ?
    ORDER BY name
    """;

// JSON payload with quotes that need no escaping
String payload = """
    {
      "user": "ada",
      "roles": ["admin", "editor"]
    }
    """;

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

Текстовые блоки в действии

Пример ниже демонстрирует все возможности: удаление случайных пробелов, formatted() для подстановки значений, поток lines(), экранирования \s и \ в конце строки, управление отступами с помощью разделителя, а также встроенные кавычки без экранирования. Читайте комментарии — каждая строка соответствует одному правилу выше.

java— editable, runs on the server

Что можно извлечь из результата выполнения:

  • Необработанный блок выводит <html> с левого края, хотя в исходном коде он был с отступом, поскольку общий случайный пробел был удалён относительно закрывающего """.
  • formatted("World") подставляет заполнитель %s, доказывая, что текстовый блок — это обычная String, которую можно передавать методам форматирования.
  • Line count: 5 получается из html.lines(), перебирающего пять строк содержимого; завершающий символ новой строки, добавляемый закрывающим """ на отдельной строке, завершает последнюю строку, а не создаёт пустую шестую.
  • Has trailing space: true показывает, что \s принудил пробел сохраниться там, где компилятор иначе удалил бы его как случайный.
  • Continuation: Roses are red, violets are blue. доказывает, что \ в конце строки объединил две строки источника в одну, а {"name": "Ada", "active": true} выведен без единой экранированной кавычки.

Практика

Практика
Что определяет, сколько ведущих пробелов удаляется из каждой строки текстового блока Java?
Что определяет, сколько ведущих пробелов удаляется из каждой строки текстового блока Java?
Was this page helpful?