Skip to main content

Command Palette

Search for a command to run...

Text Block, """

Published
6 min readView as Markdown
V

Senior Backend Engineer with 15 years of experience specializing in Java, Spring Boot, and Cloud Architecture (AWS). Passionate about clean code, performance tuning, and mentoring the next generation of developers.

How you are writing your SQL query in your JAVA file ?, In the world of Java programming, writing SQL queries within your Java files has often been a cumbersome task, especially when it comes to maintaining readability and manageability. Traditionally, developers have relied on concatenating strings using symbols like “, +”, \n to construct multi-line SQL queries, which can quickly become messy and error-prone. However, with the introduction of Java 17, a new feature called Text Blocks offers a much cleaner and more efficient way to handle multi-line strings. Text Blocks allow you to write SQL queries and other long strings in a more readable and organized manner, eliminating the need for awkward concatenations and escape sequences. If you're using Java 17 and still relying on the old method, it's time to embrace this modern approach and enhance the clarity and maintainability of your code.

// Before Java 17 way

public class DatabaseConfig {
    // Defined constants for use in the query
    public static final String TABLE_NAME = "enterprise_user_registry";
    public static final String DEFAULT_ROLE = "'GUEST'";
    public static final String SECURITY_ACTIVE = "'ENABLED'";

    public static void main(String[] args) {
        // Multi-line query using string concatenation and explicit newlines
        String sql = "INSERT INTO " + TABLE_NAME + " (\n" +
                     "    user_guid, username, email_address, \n" +
                     "    account_role, security_clearance, created_at\n" +
                     ")\n" +
                     "VALUES (\n" +
                     "    ?, ?, ?, \n" +
                     "    " + DEFAULT_ROLE + ", " + SECURITY_ACTIVE + ", CURRENT_TIMESTAMP\n" +
                     ")\n" +
                     "ON CONFLICT (user_guid) DO UPDATE SET\n" +
                     "    username = EXCLUDED.username,\n" +
                     "    email_address = EXCLUDED.email_address,\n" +
                     "    updated_at = CURRENT_TIMESTAMP;";

        System.out.println("Generated Query:\n" + sql);
    }
}

Lets learn how to write Text Blocks in Java 17, It starts with “““ and ends with “““

public class DatabaseConfig {
    // Defined constants for use in the query
    public static final String TABLE_NAME = "enterprise_user_registry";
    public static final String DEFAULT_ROLE = "'GUEST'";
    public static final String SECURITY_ACTIVE = "'ENABLED'";

    public static void main(String[] args) {
        // Multi-line query using Java 17 Text Block and .replace()
        String sql = """
            INSERT INTO {TABLE} (
                user_guid, 
                username, 
                email_address, 
                account_role, 
                security_clearance, 
                created_at
            )
            VALUES (
                ?, ?, ?, 
                {ROLE}, {SECURITY}, CURRENT_TIMESTAMP
            )
            ON CONFLICT (user_guid) DO UPDATE SET
                username = EXCLUDED.username,
                email_address = EXCLUDED.email_address,
                updated_at = CURRENT_TIMESTAMP;
            """
            .replace("{TABLE}", TABLE_NAME)
            .replace("{ROLE}", DEFAULT_ROLE)
            .replace("{SECURITY}", SECURITY_ACTIVE);

        System.out.println("Generated Query:\n" + sql);
    }
}

                        ------------------- OR -----------------


public class DatabaseConfig {
    // Defined constants for use in the query
    public static final String TABLE_NAME = "enterprise_user_registry";
    public static final String DEFAULT_ROLE = "'GUEST'";
    public static final String SECURITY_ACTIVE = "'ENABLED'";

    public static void main(String[] args) {
        // Multi-line query using Java 17 Text Block and .formatted()
        String sql = """
            INSERT INTO %s (
                user_guid, 
                username, 
                email_address, 
                account_role, 
                security_clearance, 
                created_at
            )
            VALUES (
                ?, ?, ?, 
                %s, %s, CURRENT_TIMESTAMP
            )
            ON CONFLICT (user_guid) DO UPDATE SET
                username = EXCLUDED.username,
                email_address = EXCLUDED.email_address,
                updated_at = CURRENT_TIMESTAMP;
            """
            .formatted(TABLE_NAME, DEFAULT_ROLE, SECURITY_ACTIVE);

        System.out.println("Generated Query:\n" + sql);
    }
}

In Java 17+, Text Blocks (""") provide a powerful way to write multi-line strings, such as SQL or JSON, exactly as they appear without the clutter of concatenation (+) or escape characters like \n. Unlike traditional strings, text blocks automatically handle indentation through a process called "incidental whitespace stripping," ensuring that the code remains readable while the resulting string is clean. To inject dynamic data into these blocks, developers typically use .replace() for explicit, named placeholder swaps or .formatted() for positional, type-safe injection similar to printf.

Choosing Between .replace() and .formatted()

MethodBest Use CaseKey AdvantagesPotential Downside
.replace()Structural changes like Table or Schema names.Highly readable; you see exactly what is being replaced (e.g., {TABLE}).Less efficient for many replacements; creates multiple temporary strings in memory.
.formatted()Data values like IDs, Statuses, or User Input.Type-safe; supports complex formatting (dates, decimals) and is up to 3x faster than .replace() for multiple values.Can be harder to read if there are many %s placeholders, as you must track order carefully.

As of late 2025, the standard recommendation is to use .replace() for structural elements that only change occasionally (like table names) and .formatted() for data values that vary frequently. This hybrid approach maximizes code clarity while maintaining performance. Note that while String Templates (STR."...") were finalized in later Java versions (Java 24+), Text Blocks with .formatted() remain the industry standard for stable LTS environments like Java 17.

Sample Text Block Interview Questions

  • Q1: What is the mandatory rule for the opening delimiter of a Text Block?

    • Answer: A text block must begin with three double-quote characters (""") followed immediately by a line terminator. You cannot place the content on the same line as the opening quotes; doing so will result in a compilation error.
  • Q2: Explain the concept of "Incidental Whitespace Stripping."

    • Answer: The Java compiler automatically removes leading whitespace that is common to every line in the block. This allows you to indent the block within your code for readability without those indentation spaces becoming part of the actual string value.
  • Q3: How does the position of the closing delimiter (""") affect the resulting string?

    • Answer: The closing quotes determine the "left margin". If the closing quotes are placed further to the left than the text, it adds leading spaces to every line. If they are aligned with the text, those leading spaces are stripped.
  • Q4: How do you preserve trailing whitespace in a Text Block line?

    • Answer: By default, the compiler strips trailing whitespace. To keep it, you must use the escape sequence \s (introduced in Java 15) or an octal escape like \040.
  • Q5: What is the purpose of the backslash (\) escape character at the end of a line in a Text Block?

    • Answer: It acts as a line-continuation marker. It prevents the compiler from inserting a newline character at the end of that specific line, allowing you to break a single long line of text across multiple lines in your source code for better readability.
  • Q6: Compare .replace() vs .formatted() when used with Text Blocks.

    • Answer: Use .replace() for structural placeholders (like {TABLE_NAME}) that are easier to read and identify. Use .formatted() for injecting multiple data values in order, as it is more efficient and provides type-safety for numbers and dates.
  • Q7: How does Java handle a mix of tabs and spaces in Text Block indentation?

    • Answer: The compiler treats each whitespace character equally as having a "width of one". Mixing them can lead to "inconsistent indentation" warnings if you use the -Xlint:text-blocks compiler flag, as different IDEs might display them differently.
  • Q8: Are there performance differences between Text Blocks and standard string concatenation?

    • Answer: No. Text blocks are purely a compile-time feature. They compile into the exact same String object in bytecode as a traditional string literal would, so there is zero runtime performance penalty for using them.

Quick Comparison Table for Interviews

FeatureTraditional String ConcatenationJava 17 Text Block
NewlinesRequires explicit \nAutomatic based on line breaks
Escaping QuotesMust escape all double quotes (\")Quotes can be used freely
ReadabilityHard to read with + and \nHigh; resembles the final output
IndentationManual and often messyAutomatic (Incidental stripping)