Как я могу добавить переменные в функцию текстового блока Java 15?

Только что наткнулся на новую функцию в Java 15, то есть "ТЕКСТОВЫЕ БЛОКИ". Я могу предположить, что переменная может быть добавлена ​​внутри текстового блока путем объединения с оператором "+", как показано ниже:

String html = """
          <html>
              <body>
                  <p>Hello, """+strA+"""</p>
              </body>
          </html>
          """;

Но предоставляют ли они какой-либо способ, чтобы мы могли добавлять переменные способом, который становится популярным среди многих других языков, как показано ниже:

String html = """
          <html>
              <body>
                  <p>Hello, ${strA}</p>
              </body>
          </html>
          """;

Этот вопрос может показаться глупым, но в определенных ситуациях он может оказаться полезным.

3 ответа

Решение

Из спецификации текстовых блоков:

Текстовые блоки не поддерживают прямую интерполяцию строк. Интерполяция может быть рассмотрена в будущем JEP.

Значение "строковой интерполяции"

оценка строкового литерала, содержащего один или несколько заполнителей, с получением результата, в котором заполнители заменяются соответствующими значениями

из Википедии


Как было сказано выше, возможно, мы получим это в будущем. Хотя трудно сказать, как они могли бы реализовать это без нарушения обратной совместимости - что произойдет, если моя строка содержит${}, например? Разработчики языка Java редко добавляют что-либо, что может нарушить обратную совместимость.

Мне кажется, им лучше либо немедленно поддержать, либо никогда.

Возможно, это станет возможным с новым видом текстового блока. Вместо того, чтобы быть разделителем""", они могли бы использовать ''' для обозначения параметризованного текстового блока, например.

Java 15 не поддерживает интерполяцию непосредственно в текстовых блоках или простых строковых литералах.

Решение в Java 15 - использовать String.formatted()метод:

String html = """
      <html>
          <body>
              <p>Hello, %s</p>
          </body>
      </html>
      """.formatted(strA);

Как уже говорилось, это невозможно в JDK15, и вы не можете изменить этот факт.

Но, я полагаю, вы пытаетесь предложить нечто подобное на языке C#.

https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/tokens/interpolated

Хотя это всего лишь синтаксический сахар, string.Format() метод в C# (который является аналогом String.format()в Java), по-видимому, было бы хорошо, если бы мы могли иметь это в Java. Это расширение существующего способа описания строкового литерала в синтаксисе языка, но, конечно, его также можно легко адаптировать к спецификации текстового блока.

Если вы об этом думаете, вы можете предложить процессу сообщества Java расширить спецификацию языка Java. Это намного более легкое улучшение синтаксиса / семантики, чем добавление полнофункционального механизма шаблонов в спецификацию Java Compiler / Runtime, и возможно, что они согласятся с вами.

Как отметил пользователь @Michael: Нет. "Они" (команда Project Amber, которая реализует JEP 368) не предоставляют никакого способа интерполировать строку в текстовом блоке.

Заметьте, я несколько сомневаюсь, что это когда-нибудь случится. Во-первых, существует проблема обратной совместимости; любая такая попытка ввести интерполяцию требует некоторого маркера, чтобы любые существующие текстовые блоки не внезапно меняли свое значение в зависимости от того, какая версияjavac вызывать.

Но, что более важно, вы сами, задавая вопрос, не можете даже привести действительный пример, который, возможно, свидетельствует о том, что эта функция менее полезна, чем кажется. Похоже, вы придумали допустимый вариант использования, но на самом деле это не так: если то, что вы написали, компилируется и работает, значит, вы просто написали веб-приложение с довольно серьезной утечкой безопасности XSS!

Дело в том, что вам действительно нужно "создание шаблонов", и хотя создание шаблонов звучит очень просто (просто оцените это выражение, а затем вставьте результат в строку прямо там, где я ввел выражение, пожалуйста!) - это просто не так. Побег - большая причина для этого. Но вы не можете применить правило, что${strA} в текстовом блоке означает: Оценить выражение strA, затем HTML избегает этого, а затем вставляет его по двум причинам: кто говорит, что строка, в которую вы вставляете вещи, - это HTML, а не, скажем, JSON, TOML, CSV или еще что-то, и кто говорит, что интерполяция, которую я хочу, требует убежать в первую очередь? Что, если я хочу динамически вводить<em> или нет, и я не хочу, чтобы это превратилось в &lt;em&gt;?

Либо мы обновляем langspec, чтобы удовлетворить все эти случаи, и теперь мы изобретаем целую систему шаблонов и вставляем ее в языковую спецификацию, которая кажется работой, намного лучше подходящей для выделенной библиотеки, либо мы этого не делаем, и функция кажется довольно полезным, но на самом деле является нишевым: либо вы редко используете его, либо у вас есть проблемы с безопасностью и другие ошибки по всей базе кода - любая функция языка, которая вызывает злоупотребления, и я надеюсь, что кто-то согласится со мной в этом - не отличная особенность.

Да, многие языки имеют это, но нынешние люди, которые должны решить, какие функции языка Java сделать его в будущих версиях языка, похоже, находятся на этапе, когда они признают, что такие функции существуют, и извлекут уроки из этого, но не будут добавить функции в java "просто потому, что они есть во всех этих других языках" - некоторые мысли и варианты использования всегда рассматриваются в первую очередь, и любой такой анализ интерполяции строковых литералов, вероятно, приводит к: "Эх, вероятно, не стоящее дополнение к языку ".

Другие вопросы по тегам