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

huangapple go评论170阅读模式
英文:

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

问题

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

String html = """
          <html>
              <body>
                  <p>Hello, """ + strA + """</p>
              </body>
          </html>
          """;
但是他们是否提供了任何方法使我们可以像许多其他语言中那样以以下方式添加变量这种方式在许多情况下都变得流行

```java
String html = """
          <html>
              <body>
                  <p>Hello, ${strA}</p>
              </body>
          </html>
          """;
这个问题可能听起来有点傻但在某些情况下可能会很有用
英文:

Just came across a new feature in Java 15 i.e. "TEXT BLOCKS". I can assume that a variable can be added inside a text block by concatenating with a "+" operator as below:

String html = &quot;&quot;&quot;
          &lt;html&gt;
              &lt;body&gt;
                  &lt;p&gt;Hello, &quot;&quot;&quot;+strA+&quot;&quot;&quot;&lt;/p&gt;
              &lt;/body&gt;
          &lt;/html&gt;
          &quot;&quot;&quot;;

But are they providing any way so that we can add variables the way which is becoming popular among many other languages as below:

String html = &quot;&quot;&quot;
          &lt;html&gt;
              &lt;body&gt;
                  &lt;p&gt;Hello, ${strA}&lt;/p&gt;
              &lt;/body&gt;
          &lt;/html&gt;
          &quot;&quot;&quot;;

This question might sound silly but it may be useful in certain scenario.

答案1

得分: 31

Java 15不直接支持文本块内部的插值,也不支持普通字符串文字中的插值。

在Java 15中的解决方案是使用 String.formatted() 方法

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

Java 15 does not support interpolation directly within text blocks nor plain string literals.

The solution in Java 15 is to use String.formatted() method:

String html = &quot;&quot;&quot;
      &lt;html&gt;
          &lt;body&gt;
              &lt;p&gt;Hello, %s&lt;/p&gt;
          &lt;/body&gt;
      &lt;/html&gt;
      &quot;&quot;&quot;.formatted(strA);

答案2

得分: 7

文本块规范中:

> 文本块不直接支持字符串插值。
> 插值可能会在未来的JEP中考虑。

"字符串插值" 的意思是

> 计算一个包含一个或多个占位符的字符串文字,
> 生成一个结果,其中占位符被替换为它们的
> 相应值

来自Wikipedia


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

在我看来,他们最好立即支持它,或者永远不支持。

也许可以通过一种新的文本块来实现。而不是使用 &quot;&quot;&quot; 作为分隔符,他们可以使用 &#39;&#39;&#39; 来表示一个参数化的文本块,例如。

英文:

From the spec for text blocks:

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

"String interpolation" meaning

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

from Wikipedia


As stated above, maybe we'll get it in the future. Though it is difficult to say how they could possibly implement that without breaking backwards compatibility -- what happens if my string contains ${}, for example? The Java language designers rarely add anything that is likely to break backwards compatibility.

It seems to me that they would be better off either supporting it immediately, or never.

Maybe it would be possible with a new kind of text block. Rather than the delimiter being &quot;&quot;&quot;, they could use &#39;&#39;&#39; to denote a parameterized text block, for example.

答案3

得分: 0

如前所讨论,这在JDK 15中是不可能的,您无法改变这个事实。

但是,我想您可能正在尝试在C#语言中提出类似的建议。

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

如果这是您所考虑的内容,您可以向Java社区流程提出建议,以扩展Java语言规范。这与在Java编译器/运行时规范中添加全功能模板引擎相比,是一种轻量级的语法/语义增强,他们有可能会同意您的建议。

英文:

As already discussed, this is not possible in JDK15 and you cannot change that fact.

But, I suppose you are trying to suggest a thing like this in C# language.

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

Although this is just a syntax sugar thing over string.Format() method in C# (which is a counterpart of String.format() in Java), apparently it is nice if we can have this in Java. This is an extension to the existing way of describing string literal in the language syntax, but of course this can be easily adapted onto text block specification as well.

If this is what you have in your mind, you can make a proposal to Java Community Process to expand Java Language Specification. This is very much lighter syntax/semantics enhancement than adding full-featured template engine in Java Compiler/Runtime specification, and it is possible that they would agree with you.

答案4

得分: -1

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

需要注意的是,我有些怀疑这可能永远不会发生。首先,存在向后兼容性问题;任何引入插值的尝试都需要一些标记,以使任何现有的文本块不会突然根据要调用的 javac 版本而改变其意义。

但更重要的是,你自己提出的问题,甚至无法提供一个有效的示例,这或许表明这个功能并没有听起来那么有用。看起来你提出了一个有效的用例,但事实并非如此:如果你所写的可以编译并且能工作,那么你刚刚编写了一个存在严重 XSS 安全漏洞的 Web 应用!

关键是,你真正想要的是 '模板化',虽然模板化听起来很简单(只需计算这个表达式,然后将结果放入我键入表达式的字符串中!),但事实并非如此。转义是其中一个主要原因。但你不能简单地将文本块中的 ${strA} 规则应用于:计算表达式 strA,然后对其进行 HTML 转义,然后放入其中,有两个原因:首先,谁说你要将插值放入的字符串是 HTML,而不是 JSON、TOML、CSV 或其他什么,其次,谁说我所需的插值首先需要转义?如果我想要动态地注入 &lt;em&gt; 或者不想要这变成 &amp;lt;em&amp;gt; 呢?

要么我们更新语言规范以满足所有这些情况,现在我们正在创造一个完整的模板化系统并将其放入一个语言规范中,这似乎更适合于一个专用库来完成,要么我们不这样做,而这个功能似乎非常有用,但实际上很狭隘:要么你很少使用它,要么你的代码库中到处都是安全和其他 bug - 任何容易被滥用的语言特性都不是一个好特性。

是的,许多语言都有这个功能,但目前决定哪些 Java 语言特性进入未来版本的人似乎正处于这样一个阶段:他们承认这些特性存在,并且会从中吸取教训,但不会因为所有这些其他语言都有这个功能就向 Java 中添加特性 - 总是会首先考虑一些思考和用例,而对字符串字面值的插值进行任何此类分析可能会导致:“嗯,可能不值得将其添加到语言中”。

英文:

As user @Michael mentioned: No. 'they' (team Project Amber, who are implementing JEP 368) are not providing any way to interpolate the string in the text block.

Note that I somewhat doubt it'll ever happen. For starters, there is the backwards compatibility issue; any such attempt to introduce interpolation requires some marker so that any existing text blocks aren't all of a sudden going to change in what it means depending on which version of javac to invoke.

But more to the point, you yourself, asking the question, can't even come up with a valid example, which is perhaps indicative that this feature is less useful than it sounds. It looks like you came up with a valid use case, but that's not actually true: If what you wrote would compile and work, then you just wrote a webapp with a rather serious XSS security leak in it!

The point is, what you really want is 'templating', and whilst templating sounds real simple (just evaluate this expression then shove the result into the string right where I typed the expression, please!) - it just isn't. Escaping is a large reason for that. But you can't blanket-apply the rule that ${strA} in a text block means: Evaluate expression strA, then HTML escape that, then put it in, for two reasons: Who says that the string you're interpolating things into is HTML and not, say, JSON or TOML or CSV or whatnot, and who says that the interpolation I desire requires escaping in the first place? What if I want to dynamically inject &lt;em&gt; or not, and I don't want this to turn into &amp;lt;em&amp;gt;?

Either we update the langspec to cater to all these cases and now we're inventing an entire templating system and shoving that into a lang spec which seems like a job far better suited to a dedicated library, or we don't, and the feature seems quite useful but is in fact niche: Either you rarely use it, or you have security and other bugs all over your code base - any lang feature that invites abuse is, and I'd hope one would agree with me on this - not a great feature.

Yes, many languages have this, but the current folks who get to decide what java language features make it into future versions of the language seem to be in the phase that they acknowledge such features exist and will learn lessons from it, but won't add features to java 'just because all these other languages all have it' - some thought and use cases are always considered first, and any such analysis of interpolation on string literals probably leads to: "Eh, probably not a worthwhile addition to the language".

huangapple
  • 本文由 发表于 2020年9月1日 20:22:35
  • 转载请务必保留本文链接:https://go.coder-hub.com/63687580.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定