49

How can I put a variable into Java Text Block?

Like this:

"""
{
    "someKey": "someValue",
    "date": "${LocalDate.now()}",

}
"""
4
  • 2
    Its a representation of a String after all. At least for now without further detail over "why not try using an existing construct like String.format" , the question would stand as an exact duplicate. Leaving the rest for the community to decide. Commented Apr 26, 2020 at 0:20
  • 1
    Does this answer your question Java - Including variables within strings? Commented Apr 26, 2020 at 0:24
  • I thought more about how to write java code inside the text block, String.format is more like a work around with which sadly I hadn't come up with... Commented Apr 26, 2020 at 0:41
  • 2
    @DennisGlot String::format is not a workaround, it is the normal way of doing string interpolation in Java. (With text blocks, an instance version was also added, so you can say "...".formatted(...) if you prefer chaining.) Commented Apr 26, 2020 at 15:29

3 Answers 3

61

You can use %s as a placeholder in text blocks:

String str = """
{
    "someKey": "someValue",
    "date": %s,
}
"""

and replace it using format() method.

String.format(str, LocalDate.now());

From JEP 378 docs:

A cleaner alternative is to use String::replace or String::format, as follows:

String code = """
          public void print($type o) {
              System.out.println(Objects.toString(o));
          }
          """.replace("$type", type);

String code = String.format("""
          public void print(%s o) {
              System.out.println(Objects.toString(o));
          }
          """, type);

Another alternative involves the introduction of a new instance method, String::formatted, which could be used as follows:

String source = """
            public void print(%s object) {
                System.out.println(Objects.toString(object));
            }
            """.formatted(type);

NOTE

Despite that in the Java version 13 the formatted() method was marked as deprecated, since Java version 15 formatted(Object... args) method is officially part of the Java language, same as the Text Blocks feature itself.

Sign up to request clarification or add additional context in comments.

6 Comments

Could you explain, why is this not a duplicate of stackoverflow.com/questions/9643610/…?
@Naman Because that question is about conventional string syntax, while this question is specifically about text blocks.
String.formatted is not "really" deprecated. In fact, it is a new method (since Java 13). It is deprecated only because it is related to text blocks, which are a preview feature. But if you use text blocks, you can as well use this method.
|
6

You can use Java's String Templates feature. It is described in JEP 430, and it appears in JDK 21 as a preview feature. Here is an example use:

String name = "Joan";
String info = STR."My name is \{name}";
assert info.equals("My name is Joan");   // true

It also supports Java's multi-line text blocks:

String title = "My Web Page";
String text  = "Hello, world";
String html = STR."""
        <html>
          <head>
            <title>\{title}</title>
          </head>
          <body>
            <p>\{text}</p>
          </body>
        </html>
        """;

Java's string templates are more versatile, and much safer, than features in other languagues such as C#'s string interpolation and Python's f-strings. For example, here is a template processor that returns not strings but, rather, instances of JSONObject:

var JSON = StringTemplate.Processor.of(
        (StringTemplate st) -> new JSONObject(st.interpolate())
    );

String name    = "Joan Smith";
String phone   = "555-123-4567";
String address = "1 Maple Drive, Anytown";
JSONObject doc = JSON."""
    {
        "name":    "\{name}",
        "phone":   "\{phone}",
        "address": "\{address}"
    };
    """;

1 Comment

Was this abandoned? openjdk.org/jeps/465
1

You can use Java's String Templates feature. It is described in JEP 430, and it appears in JDK 21 as a preview feature. Here is an example single-line use:

String name = "Joan";
String info = STR."My name is \{name}";
assert info.equals("My name is Joan");   // true

It also supports Java's multi-line text blocks:

String title = "My Web Page";
String text  = "Hello, world";
String html = STR."""
        <html>
          <head>
            <title>\{title}</title>
          </head>
          <body>
            <p>\{text}</p>
          </body>
        </html>
        """;

Java's string templates are more versatile, and much safer, than features in other languagues such as C#'s string interpolation and Python's f-strings. For example, string concatenation or interpolation makes SQL injection attacks possible:

String query = "SELECT * FROM Person p WHERE p.last_name = '" + name + "'";
ResultSet rs = conn.createStatement().executeQuery(query);

but this variant (from JEP 430) prevents SQL injection:

PreparedStatement ps = DB."SELECT * FROM Person p WHERE p.last_name = \{name}";
ResultSet rs = ps.executeQuery();

and you could do something similar to create an HTML data structure, via a string template that quotes HTML entities.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.