如何在 Java 15 文本块功能中添加变量?

How can i add variables inside Java 15 text block feature?

刚刚在 Java 15 中发现了一项新功能,即“文本块”。我可以假设可以通过连接“+”运算符将变量添加到文本块中,如下所示:

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

但是他们是否提供了任何方式,以便我们可以按照以下在许多其他语言中变得流行的方式添加变量:

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

这个问题听起来可能很傻,但在某些情况下可能会有用。

来自the spec for text blocks

Text blocks do not directly support string interpolation. Interpolation may be considered in a future JEP.

“字符串插值”含义

evaluating a string literal containing one or more placeholders, yielding a result in which the placeholders are replaced with their corresponding values

来自 Wikipedia


如上所述,也许我们将来会得到它。尽管很难说他们如何在不破坏向后兼容性的情况下实现它——例如,如果我的字符串包含 ${} 会发生什么? Java 语言设计者很少添加任何可能破坏向后兼容性的内容。

在我看来,他们最好要么立即支持,要么永远不支持。

也许可以使用一种新的文本块。例如,他们可以使用 ''' 来表示参数化文本块,而不是分隔符 """

正如用户@Michael 提到的那样:不。'they'(正在实施 JEP 368 的 Project Amber 团队)没有提供在文本块中插入字符串的任何方法。

请注意,我有点怀疑它是否会发生。对于初学者来说,存在向后兼容性问题;任何此类引入插值的尝试都需要一些标记,这样任何现有的文本块都不会突然改变其含义,具体取决于要调用的 javac 版本。

但更重要的是,您自己提出问题时甚至无法举出有效的示例,这可能表明此功能没有听起来那么有用。看起来您提出了一个有效的用例,但实际上并非如此:如果您编写的内容可以编译并工作,那么您只是编写了一个存在相当严重的 XSS 安全漏洞的 Web 应用程序!

重点是,您真正想要的是 'templating',虽然模板听起来很简单(只需计算这个表达式,然后将结果推到我输入表达式的字符串中,拜托!)- 它只是不是。逃避是一个很大的原因。但是你不能 blanket-apply 文本块中 ${strA} 的规则意味着:计算表达式 strA 然后 HTML 转义 ,然后把它放进去,原因有二:谁说你插入的字符串是 HTML 而不是 JSON 或 TOML 或 CSV 或诸如此类的东西,谁说插值我希望首先需要转义?如果我想动态注入或不注入 <em> 并且我不希望它变成 &lt;em&gt; 怎么办?

我们要么更新 langspec 以适应所有这些情况,现在我们正在发明一个完整的模板系统并将其推入 lang spec,这似乎是一项更适合专用库的工作,要么我们不t,并且该功能似乎非常有用,但实际上是利基:要么您很少使用它,要么您的代码库中到处都是安全性和其他错误 - 任何会引起滥用的语言功能都是,我希望有人会同意我对此 - 不是一个很好的功能。

是的,很多语言都有这个,但是现在决定哪些 java 语言特性进入该语言的未来版本的人似乎正处于他们承认这些特性存在并将继续存在的阶段从中吸取教训,但不会向 java 'just because all these other languages all have it' 添加功能 - 始终首先考虑一些想法和用例,并且任何此类对字符串文字插值的分析可能会导致:“嗯,可能对语言来说不值得。

如前所述,这在 JDK15 中是不可能的,您无法更改这一事实。

但是,我想你正试图用 C# 语言提出这样的建议。

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

虽然这只是 C# 中 string.Format() 方法的语法糖(它是 Java 中 String.format() 的对应物),但显然如果我们能拥有它就很好了在 Java。这是对语言语法中描述字符串文字的现有方式的扩展,但当然这也可以很容易地适应文本块规范。

如果这是您的想法,您可以向Java Community Process提出扩展Java语言规范的建议。这比在 Java Compiler/Runtime 规范中添加 full-featured 模板引擎要轻得多 syntax/semantics 增强,他们可能会同意你的看法。

Java 15 不支持直接在文本块内插值,也不支持纯字符串文字。

Java15中的解决方法是使用String.formatted() method:

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