BT

Facilitating the Spread of Knowledge and Innovation in Professional Software Development

Write for InfoQ

Topics

Choose your language

InfoQ Homepage News Java Gets a Boost with String Templates: Simplifying Code and Improving Security

Java Gets a Boost with String Templates: Simplifying Code and Improving Security

This item in japanese


JEP 430, String Templates (Preview), has been promoted from Proposed to Target to Targeted status for JDK 21, a feature JEP type that proposes to enhance the Java programming language with string templates, which are similar to string literals but contain embedded expressions incorporated into the string template at run time.

Java developers can now enhance the language's string literals and text blocks with string templates that can produce specialized results by coupling literal text with embedded expressions and processors. The aim of this new feature is to simplify the writing of Java programs, improve the readability of expressions that mix text and expressions, and enhance the security of Java programs that compose strings from user-provided values.

This JEP introduces a new kind of expression called a template expression that allows developers to perform string interpolation and compose strings safely and efficiently. Template expressions are programmable and not limited to composing strings. They can turn structured text into any kind of object according to domain-specific rules. In a template expression, a template processor combines the literal text in the template with the values of any embedded expressions at runtime to make a result. Examples are as follows:
 

String name = "Joan";

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

A template expression has a similar syntax to a string literal, but with a prefix. The second line of the above code contains a template expression.

In contrast, usually, String interpolation allows programmers to combine string literals and expressions into a single string, as many programming languages use, providing greater convenience and clarity than traditional string concatenation. However, it can create dangerous strings that may be misinterpreted by other systems, especially when dealing with SQL statements, HTML/XML documents, JSON snippets, shell scripts, and natural-language text. To prevent security vulnerabilities, Java requires developers to validate and sanitize strings with embedded expressions using escape or validate methods.


A safer and more efficient solution would be to introduce a first-class, template-based mechanism for composing strings that automatically applies template-specific rules to the string, resulting in escaped quotes for SQL statements, no illegal entities for HTML documents, and boilerplate-free message localization. This approach relieves developers from the manual task of escaping each embedded expression and validating the entire string. Exactly that’s what is done by the template expression that Java adheres to as opposed to String interpolation used by other popular programming languages.

The design of the template expression makes it impossible to go directly from a string literal or text block with embedded expressions to a string with the expressions' values interpolated. This is to prevent dangerously incorrect strings from spreading through the program. Instead, a template processor, such as STR, FMT or RAW, processes the string literal, validates the result, and interpolates the values of embedded expressions.

Here are some examples of template expressions that use multiple lines to describe HTML text, JSON text, and a zone form:

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

Which yields the following output:

| """
| <html>
|   <head>
|     <title>My Web Page</title>
|   </head>
|   <body>
|     <p>Hello, world</p>
|   </body>
| </html>
| """


Another example is as follows:

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

Similarly, this produces the following output.

| """
| {
|     "name":    "Joan Smith",
|     "phone":   "555-123-4567",
|     "address": "1 Maple Drive, Anytown"
| }
| """

Another example:

record Rectangle(String name, double width, double height) {
    double area() {
        return width * height;
    }
}

Rectangle[] zone = new Rectangle[] {
        new Rectangle("Alfa", 17.8, 31.4),
        new Rectangle("Bravo", 9.6, 12.4),
        new Rectangle("Charlie", 7.1, 11.23),
    };

String form = FMT."""
        Description     Width    Height     Area
        %-12s\{zone[0].name}  %7.2f\{zone[0].width}  %7.2f\{zone[0].height}     %7.2f\{zone[0].area()}
        %-12s\{zone[1].name}  %7.2f\{zone[1].width}  %7.2f\{zone[1].height}     %7.2f\{zone[1].area()}
        %-12s\{zone[2].name}  %7.2f\{zone[2].width}  %7.2f\{zone[2].height}     %7.2f\{zone[2].area()}
        \{" ".repeat(28)} Total %7.2f\{zone[0].area() + zone[1].area() + zone[2].area()}
          """;

The above code produces the following output:

| """
| Description     Width    Height     Area
| Alfa            17.80    31.40      558.92
| Bravo            9.60    12.40      119.04
| Charlie          7.10    11.23       79.73
|                              Total  757.69
| "

Java provides two template processors for performing string interpolation: STR and FMT. STR replaces each embedded expression in the template with its (stringified) value, while FMT interprets format specifiers that appear to the left of embedded expressions. The format specifiers are the same as those defined in java.util.Formatter. In cases where the unprocessed template is needed, the standard RAW template processor can be used. This processor simply returns the original template without any interpolation or processing.

Furthermore, developers can create their own template processors for use in template expressions. A template processor is an object that provides the functional interface ValidatingProcessor, and its class implements the single abstract method of ValidatingProcessor, which takes a StringTemplate and returns an object. Template processors can be customized to perform validation at runtime and return objects of any type, not just strings.

In conclusion, template expressions in Java make it easy and safe for developers to do string interpolation and string composition.

About the Author

Rate this Article

Adoption
Style

BT