Java Text Block Formatting with Variables/Expressions

Java text blocks are multiline strings, finalized in Java 15. A text block avoids the need for most escape sequences by preserving the indentations and formatting, intact. This Java tutorial will teach us to apply String interpolation (variable substitution) in text blocks.

Although, you may be tempted to use String concatenation for formatting a text block with variables and expressions, do not try this. Rather use the String.formatted() method specifically designed for this purpose.

1. Text Block Formatting with String.formatted()

This is the most cleaner and recommended way of formatting text blocks with variables. It returns a formatted string using the specified format string (text block) and arguments (variables).

Consider the following example. Here we are formatting a JSON string with variables in runtime:

int id = 1001;
String name = "John Doe";
int age = 34;

String textBlock = """
    {
      "id": %d,
      "name": "%s",
      "age": %d
    }
    """;

String formattedTextBlock = textBlock.formatted(id, name, age);
System.out.println( formattedTextBlock );

The program output:

{
  "id": 1001,
  "name": "John Doe",
  "age": 34
}

If the number of variables is very large then passing all the variables as varargs may not seem appropriate. In this case, we can pass the formatting variables as an Object[].

Object[] formatArguments = {
    1001,     // id
    "John Doe",  // name
    34       // age
}; 

String formattedTextBlock2 = textBlock.formatted(formatArguments);
System.out.println( formattedTextBlock2 );

The program output:


{
  "id": 1001,
  "name": "John Doe",
  "age": 34
}

The formatted method internally calls the String.format(string, args) method. So we can call it explicitly if we need it in any case.

String formattedTextBlock = String.format(textBlock, formatArguments);

//... OR

String formattedTextBlock = String.format(textBlock, id, name, age);

2. Text Block Formatting with MessageFormat.format()

If you are looking for localized content and complex patterns, and still not overkill for simple use cases, MessageFormat.format() is a robust choice. Note that using the MessageFormat is not as simple as String.format() method. We have to be very careful about the specific formatting patterns in the text block.

For example, if your default locale uses commas for thousands as separators then sending this field value without double quotes will generate the invalid JSON (in our case).

String json = """
    '{'
       "id": {0, number, #},
       "name": "{1}",
       "salary": "{2, number, integer}"
    '}'
    """;

Object[] arguments = {
    1001,     // id
    "John Doe",  // name
    34000       // salary
};

String formattedTextBlock3 = MessageFormat.format(json, arguments);
System.out.println(formattedTextBlock3);

The program output:

{
   "id":  1001,
   "name": "John Doe",
   "salary": "34,000"
}

When using MessageFormat, we should very carefully test all the possibilities of generated formatted strings.

3. String Concatenation (Do Not Try)

Let us try to use interpolation in a simple text block and see the output.

String name = "John Doe";
String greeting = """
              Hello, """ + name + """
              Welcome to Java text blocks!
              """;

System.out.println(greeting);

The program output:

Hello,John DoeWelcome to Java text blocks!

Why did we lose the new line? Well, text blocks preserve the exact formatting and indentation as they appear in the source code. But the above statement is not interpolation, it is the concatenation of 3 strings. The first and third are the text blocks, and the second is a simple string with the value of name variable in the runtime.

The variable name is concatenated directly next to “Hello, ” without any space or newline character. Similarly, “Welcome to Java text blocks!” is concatenated immediately after the name without any new line or space. That is the final output is a single string.

Adding escape sequences in the text patterns to achieve the desired output is a very cumbersome process and not worth it. We should rather stick to formatted() method.

4. Conclusion

Java text blocks have significantly simplified the handling of multiline strings. Incorporating variables or expressions within the text blocks, although not as straightforward as in some other languages, can be achieved efficiently using the String.formatted() method. For locale-sensitive formatting, we can use the MessageFormat.format() method.

Happy Learning !!

Source Code on Github

Comments

Subscribe
Notify of
guest
0 Comments
Inline Feedbacks
View all comments

About Us

HowToDoInJava provides tutorials and how-to guides on Java and related technologies.

It also shares the best practices, algorithms & solutions and frequently asked interview questions.