What to Expect from Java 13: New Features Explained

Java 13 reached general availability on September 17, 2019. It was a non-long-term-support release, so its features are best studied as a milestone in the evolution of the Java platform rather than as a reason to adopt an unsupported runtime for a new production project. The release illustrates three different kinds of engineering progress: language syntax under preview, JVM memory and startup improvements, and changes beneath stable networking APIs.

For a reliable historical account, distinguish the five major Java 13 enhancement proposals from smaller security and platform fixes. Later JDK versions changed or finalized some preview features, so a Java 13 example must be interpreted with the release’s original rules. Current deployments should follow a supported JDK distribution and its published migration guidance.

The five main Java 13 enhancements

OpenJDK identified JEP 350 for dynamic CDS archives, JEP 351 for ZGC returning unused heap memory, JEP 353 for reimplementing the legacy socket API, JEP 354 for preview switch expressions, and JEP 355 for preview text blocks. The first three primarily concern runtime and implementation behavior; the last two concern language syntax that was still being evaluated. Confusing these categories leads to inaccurate claims about what developers had to rewrite in 2019.

Text blocks as a preview language feature

JEP 355 introduced a preview form of multiline string literal with triple-quote delimiters. It reduced the visual noise of repeated newline and quotation-mark escaping in structured text examples. Indentation and trailing-newline rules remained important, and the feature was not yet finalized in Java 13.

String message = """
    Operation: validate
    Environment: test
    Outcome: pending
    """;

Historical Java 13 preview examples require the matching compiler and runtime preview options. A text block does not make untrusted input safe: database operations still need parameterized statements, and JSON or XML output should use appropriate serialization libraries.

Switch expressions and yield

JEP 354 continued preview work on switch expressions and introduced yield to produce a value from a block arm. Arrow-style cases could simplify selections without accidental fall-through. The language distinction between a switch statement and an expression matters when interpreting examples.

String label = switch (level) {
    case 1 -> "basic";
    case 2 -> "intermediate";
    default -> "advanced";
};

Do not assume every switch example written against the Java 13 preview has identical semantics in a later final language version. Recompile and test it against the actual JDK chosen for the project. This is especially important when educational materials describe a preview feature as universally available.

ZGC returned unused memory to the operating system

JEP 351 enhanced the Z Garbage Collector with the ability to uncommit unused heap memory. ZGC already existed before this release; Java 13 did not introduce it from scratch. Returning unneeded memory can be useful for services with fluctuating demand, but real benefits depend on allocation rates, heap sizing and the operating environment.

Measure garbage-collection pauses, throughput and host memory pressure together. A collector improvement does not guarantee that every application becomes faster or more memory-efficient.

Dynamic class-data sharing archives

JEP 350 improved class-data sharing workflows by allowing dynamic archives of class metadata to be produced from application execution. This could reduce some startup and memory overhead in suitable deployments without requiring developers to rewrite business logic.

When measuring class-data sharing, use repeatable startup workloads and record the classpath and JDK build. Cold and warm filesystem caches can influence the result. Startup optimization is only meaningful when measurements are consistent across comparable runs.

A new implementation beneath the legacy socket API

JEP 353 reimplemented the underlying socket APIs in a more maintainable form. Applications still used familiar classes such as java.net.Socket and java.net.ServerSocket. It was primarily an implementation change, not a new public networking API requiring wholesale source changes.

Compatibility testing nevertheless matters. Evaluate connection establishment, timeouts, socket closure, exceptions and operating-system-specific behavior with realistic network failures before migrating an important workload.

Security and library notes require version-specific reading

Beyond the main JEPs, the archived Java 13 release notes record library, cryptography, platform integration and security-related changes. These details are not interchangeable. A Windows-specific provider update may be irrelevant to a Linux deployment, while an option removed from the runtime may affect a particular legacy launch script.

Read the exact release-note item, identify the affected component, and check whether the application uses it. Avoid saying every update improves security or that every removed option was universally unsafe. Those conclusions require evidence beyond a version number.

How to investigate Java 13 in a lab

Use a disposable, isolated environment when exploring a historical runtime. Record the distribution and exact build. For a preview-language exercise, match the original source-level configuration and enable preview features explicitly. For runtime experiments, collect logs and timings rather than relying on descriptions.

  • Compile a preview example and compare its behavior with a supported newer language version.
  • Measure application startup with and without a suitable CDS archive.
  • Inspect ZGC memory and pause behavior under a repeatable variable-load scenario.
  • Exercise socket connection, timeout and failure handling through integration tests.
  • Map smaller release-note changes to the exact operating system or library they affect.

Never deploy an unsupported JDK into production merely to reproduce an old tutorial. For operational use, migrate to a current supported release and test application dependencies first.

Choosing a current JDK instead

In October 2026, Java 13 belongs to the historical non-LTS family. Modern long-term-support release families such as Java 21 and Java 25 may be appropriate for new projects, depending on support terms, frameworks, vendors and deployment constraints. Inventory build plugins, application servers, security libraries and preview-era code before attempting a migration.

Plan the change across CI/CD environments, containers, runtime images, observability and rollback. A successful JDK upgrade preserves correct application behavior and the team’s ability to operate the service, not just a successful compiler exit code.

Conclusion

Java 13 helped develop ideas that shaped later Java releases. Its lasting lesson is that language previews, garbage collection, class-loading optimization and API implementation changes solve different problems and demand different tests. Study the 2019 release with historical accuracy; use a supported current JDK and official migration documents for real deployment decisions.

  • img