Блоки текста запланированы к появлению в Java 13. Об этом стало известно из JEP 355.

Блоки текста — это многострочный строковый литерал, который устраняет необходимость в экранировании большинства специальных символов и автоматически делает переносы строки.

Это дальнейшая попытка исследований, начавшихся в 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)


  1. maxzh83
    30.05.2019 13:46
    +1

    Не знаю чем «вдохновлялись» создатели блоков текста, но если Скалой (а там это реализовано точно также), то хочется, чтобы вдохновились еще сильнее и сделали уже и интерполяцию.


    1. sshikov
      30.05.2019 14:00
      +1

      Ага. Самое смешное, что и в груви это реализовано сто лет как, и тоже вполне удобно. И почему бы не срисовать с хороших примеров — не ясно.



    1. KvanTTT
      30.05.2019 14:28

      Еще в Swift так же.


    1. igormich88
      30.05.2019 14:42

      И в котлине, но там я думаю из скалы взято.


      1. xxr1d3rx
        31.05.2019 09:24

        В Dart тоже.


    1. CyberSoft
      30.05.2019 18:06

      Чем и откуда вдохновляются бывает написано в самих JEPах, причём с описанием того, как "это было бы в нашем случае": как поддерживать, на что влияет, как тестировать и т.д. и т.п. (это ответ и комментаторам ниже).


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


      1. Anton23 Автор
        31.05.2019 09:28

        Да, там и описано. Точнее, там не написано чем вдохновлялись, там написано почему они не скопировали один в один из других языков:

        По словам Брайана Гетца:

        Многие люди считают, что Java должна сделать многострочные строковые литералы такими же, как в Swift или Rust. Однако подход «просто делай то, что делает язык X» по сути своей безответственен; почти каждая особенность каждого языка обусловлена ??другими особенностями этого языка. Вместо этого нужно узнать, как работают другие языки, оценить компромиссы, которые они выбрали(явным и неявным образом), и спросить, что можно применить к ограничениям языка, который у нас есть, и ожиданиям пользователей в нашем сообществе.


        Для JEP 326 (необработанные строковые литералы) мы рассмотрели многие современные языки программирования и их поддержку многострочных строковых литералов. Результаты этих опросов повлияли на текущее предложение, например, на выбор трех «символов для разделителей(хотя были и другие причины) и признание необходимости автоматического управления отступами.


    1. 0xd34df00d
      30.05.2019 22:26

      А можно было бы вдохновиться ещё сильнее (но не скалой), сделать нормальные квазиквотеры и вынести что raw string literals, что интерполяцию строк, что ещё миллион вариантов применений, на уровень библиотек.


    1. StrangerInTheKy
      31.05.2019 00:27

      Не знаю чем «вдохновлялись» создатели блоков текста
      Ну раз java принадлежит теперь ораклу, то вдохновлялись, вестимо, оракловым диалектом SQL ;)


      1. Anton23 Автор
        31.05.2019 09:24

        Ну раз java принадлежит теперь ораклу


        Теперь? Уже вроде несколько лет как.


  1. vektory79
    30.05.2019 14:09

    Интересно почему предидуший jep отменили. Выглядело неплохо…


    1. CyberSoft
      30.05.2019 17:59

      Автор не стал переводить раздел "Альтернативы", а зря. Там подробнее описывается опыт с Raw String Literals.


      Я не переводчик, но вкратце: что-то у них там не зашло с разделителями строки в её содержимом. Они хотели сделать такой случай сразу неэкранируемым, но этот вариант "плохо бы поддерживался в будущем".


  1. rmuskovets
    30.05.2019 14:23

    А не слишком сильно похоже на Python? Там так само


    1. maxzh83
      30.05.2019 14:30
      +1

      Не только в Python «так само», в JVM языках Groovy и Scala также. А еще, судя по комментариям, в C# и Swift. Просто в случае с jvm-языками, можно посмотреть как реализовано технически.


      1. Alek_roebuck
        30.05.2019 21:36
        +1

        и даже С++ последние 8 лет.


  1. Kalidratorma
    30.05.2019 14:27

    С каждым релизом Java все больше становиться похожа на C#.


    1. maxzh83
      30.05.2019 14:32

      Вы рады этому или негодуете?


      1. Kalidratorma
        30.05.2019 14:45

        Рад. Это напоминает ситуацию с iOS и Android. Изначально один был скопирован с другого, теперь черпают друг у друга фичи. Конечный пользователь выигрывает в любом случае.


      1. igormich88
        30.05.2019 16:11
        +1

        На мой взгляд проблема именно в том что идёт копирование фич, а самостоятельное развитие языка крайне неспешно. Позиция догоняющего не очень хороша. В котлине например сейчас экспериментируют с инлайн классами которых вроде бы нет в других языках (не уверен на 100%)


        1. Kalidratorma
          30.05.2019 16:45

          Я считаю, что брать лучшие практики — хорошая стратегия развития. Описание inline class Котлина напоминает делегат.


        1. AstarothAst
          31.05.2019 09:52

          Вы что, хотите, как в java script?!


        1. Enverest
          31.05.2019 13:10

          В котлине например сейчас экспериментируют с инлайн классами которых вроде бы нет в других языках (не уверен на 100%)
          Похоже на value class в Скале.


          1. Yulaw
            02.06.2019 08:39

            value class немного костыльные и не всегда работают, поэтому в скале работают над новым механизмом — opaque types
            Будет скорее всего в 2.14, возможно в 2.13 под фича флагом


  1. 0xd34df00d
    30.05.2019 22:27

    Escape-последовательности интерпретируются.

    В регулярках по-прежнему придётся эскейпить \?


  1. AnthonyDS
    31.05.2019 10:06

    Остаётся её только сделать для Enterprise Edition, а для Standard Edition и Community закрыть лицензионным соглашением…


  1. vlanko
    31.05.2019 11:01

    Выглядит отлично. Жаль, что LTS будет нескоро.