How to have placeholder for variable value in Java Text Block?

20.4k Views Asked by At

How can I put a variable into Java Text Block?

Like this:

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

}
"""
3

There are 3 best solutions below

6
On BEST ANSWER

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.

0
On

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.

0
On

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}"
    };
    """;