JDK 13 Key Features — Text Blocks and ZGC Improvements

Text Blocks (Preview)

The most anticipated feature in Java 13 is Text Blocks (JEP 355). They free you from the \n and + concatenation nightmare when writing multi-line strings.

Think of an email template. Previously it felt like gluing each line of a letter together piece by piece, while Text Blocks feel like writing naturally on a single sheet of paper.

Basic Usage

public class TextBlockBasic {
    public static void main(String[] args) {
        // === Old way: escape and concatenation operator hell ===
        String jsonOld = "{\n" +
            "    \"name\": \"John Doe\",\n" +
            "    \"age\": 30,\n" +
            "    \"city\": \"Seoul\"\n" +
            "}";

        // === Text Block: stored exactly as it appears ===
        String jsonNew = """
                {
                    "name": "John Doe",
                    "age": 30,
                    "city": "Seoul"
                }
                """;

        System.out.println("Old way:");
        System.out.println(jsonOld);
        System.out.println();
        System.out.println("Text Block:");
        System.out.println(jsonNew);
        System.out.println("Are both strings equal? " + jsonOld.equals(jsonNew.strip()));
        // Output:
        // Old way:
        // {
        //     "name": "John Doe",
        //     "age": 30,
        //     "city": "Seoul"
        // }
        //
        // Text Block:
        // {
        //     "name": "John Doe",
        //     "age": 30,
        //     "city": "Seoul"
        // }
        //
        // Are both strings equal? true
    }
}

Text Blocks start and end with """ (three quotation marks). The opening """ must be followed by a line break. Indentation is automatically aligned based on the position of the closing """.

Indentation Control

Text Block indentation follows a rule where common leading whitespace is automatically removed. The position of the closing """ serves as the baseline.

public class TextBlockIndent {
    public static void main(String[] args) {
        // Moving the closing """ to the left preserves indentation
        String html = """
<html>
    <body>
        <p>No indentation</p>
    </body>
</html>
""";

        // Moving the closing """ to the right applies relative indentation
        String htmlIndented = """
                <html>
                    <body>
                        <p>4-space indentation</p>
                    </body>
                </html>
                """;

        System.out.println("No indentation:");
        System.out.println(html);
        System.out.println("With indentation:");
        System.out.println(htmlIndented);
        // Output:
        // No indentation:
        // <html>
        //     <body>
        //         <p>No indentation</p>
        //     </body>
        // </html>
        //
        // With indentation:
        // <html>
        //     <body>
        //         <p>4-space indentation</p>
        //     </body>
        // </html>
    }
}

Switch Expressions Improved — yield Keyword

Switch Expressions, introduced as a preview in Java 12, received a key improvement in Java 13 (JEP 354). The main change is the introduction of the yield keyword.

The arrow (->) syntax works well for returning single expressions, but when you need to return a value after complex logic within a block, you use yield.

public class SwitchYieldDemo {
    public static void main(String[] args) {
        String day = "WEDNESDAY";

        // === Arrow syntax: simple value return ===
        int letters = switch (day) {
            case "MONDAY", "FRIDAY", "SUNDAY" -> 6;
            case "TUESDAY" -> 7;
            case "WEDNESDAY", "THURSDAY", "SATURDAY" -> {
                // Use yield to return a value when a block is needed
                System.out.println("Processing " + day + "...");
                yield day.length();
            }
            default -> throw new IllegalArgumentException("Unknown day: " + day);
        };

        System.out.println(day + " -> " + letters + " letters");

        // === yield can also be used with colon (:) syntax ===
        String season = switch (day) {
            case "MONDAY":
            case "TUESDAY":
                yield "Early weekday";
            case "WEDNESDAY":
                yield "Midweek";
            case "THURSDAY":
            case "FRIDAY":
                yield "Late weekday";
            default:
                yield "Weekend";
        };

        System.out.println(day + " -> " + season);
        // Output:
        // Processing WEDNESDAY...
        // WEDNESDAY -> 9 letters
        // WEDNESDAY -> Midweek
    }
}

yield is a keyword exclusive to switch expressions. It replaces the Java 12 approach of using break to return values (break value;). This change creates a clear separation of responsibilities: break for loop control and yield for switch value return.

ZGC Memory Return (JEP 351)

ZGC (Z Garbage Collector), introduced experimentally in Java 11, gained the ability to return unused heap memory to the OS in Java 13.

Previously, ZGC held onto memory it had acquired indefinitely. After traffic spikes, memory wouldn’t return to its original level, making it inefficient in container environments.

# Enable ZGC and configure memory return
java -XX:+UnlockExperimentalVMOptions \
     -XX:+UseZGC \
     -XX:ZUncommitDelay=300 \
     -jar your-app.jar

# ZUncommitDelay: Wait time before returning unused memory (seconds, default 300)
EnvironmentExpected Benefit
Kubernetes PodMemory returned during traffic drops -> cluster resource savings
Shared ServerMemory reclaimed from idle applications
Development EnvironmentReduced memory usage from multiple JVM processes

Socket API Reimplementation (JEP 353)

The internal implementation of java.net.Socket and java.net.ServerSocket was replaced with NioSocketImpl. The original implementation (PlainSocketImpl) was legacy code dating back to JDK 1.0.

No external API changes were made, so existing code doesn’t need modification. The internal switch to NIO-based implementation improves maintainability and lays the groundwork for future Virtual Thread (Java 21) integration.

Dynamic CDS Archives (JEP 350)

CDS (Class Data Sharing) is a technology that reduces JVM startup time. It pre-stores class metadata in a shared archive and reuses it on the next run.

Java 13 allows CDS archives to be automatically generated at application shutdown. Previously, a separate trial run was required.

# Step 1: Run the application and auto-generate a CDS archive
java -XX:ArchiveClassesAtExit=app-cds.jsa -jar your-app.jar

# Step 2: Subsequent runs use the archive -> faster startup
java -XX:SharedArchiveFile=app-cds.jsa -jar your-app.jar

In microservices environments where dozens of instances start simultaneously, CDS can reduce startup time by 20-30%.

Practical Tips

FeatureUse Cases
Text BlocksImmediately applicable for multi-line strings like JSON, HTML, SQL
yieldUse when complex logic is needed within a switch block
ZGC Memory ReturnMemory efficiency improvement in container environments
Dynamic CDSStartup time optimization for microservices
NioSocketImplAutomatically applied without code changes (when using Java 13+)

Java 13 is a release focused on maturing existing features rather than introducing major changes. Text Blocks become finalized in Java 15, and the Switch Expressions yield keyword is finalized in Java 14. Since all preview features from this period become final in Java 14-15, Java 13 serves as a “transitional bridge” version.

Was this article helpful?