Why Collection Factory Methods? Before Java 9, creating a small immutable collection was tedious: // Java 8 — three lines, two classes, mutable intermediate List<String> names = Collections.unmodifiableList( Arrays.asList("Alice", "Bob", "Charlie") ); // Java 8 — even worse for Map Map<String, Integer> scores = new HashMap<>(); scores.put("Alice", 90); scores.put("Bob", 85); Map<String, Integer> immutableScores = Collections.unmodifiableMap(scores); JEP 269 (Java 9) introduced static factory methods that create truly immutable collections with a single expression:
Continue reading »Java11
18 posts in this section
Files and IO Enhancements (Java 11)
The Problem: File IO Boilerplate Reading a file’s content in Java 8 required several lines of boilerplate, even for simple tasks: // Java 8 — read entire file as String String content; try (var reader = new BufferedReader(new FileReader("config.txt"))) { content = reader.lines().collect(Collectors.joining("\n")); } // Java 8 — write a String to a file try (var writer = new BufferedWriter(new FileWriter("output.txt"))) { writer.write(content); } Java 11 reduced this to one-liners.
Continue reading »Flight Recorder and JVM Monitoring (JEP 328)
What Is Java Flight Recorder? Java Flight Recorder (JFR) is a low-overhead, always-on profiling and diagnostics framework built into the JVM. It was a commercial feature of Oracle JDK until JEP 328 (Java 11) open-sourced it as part of OpenJDK. JFR collects data about JVM internals and application behaviour — method profiling, allocation, GC pauses, thread states, I/O, lock contention — with a typical overhead of 1–2% in production. This makes it fundamentally different from traditional profilers (JProfiler, YourKit): those profilers cause 10–50% overhead, making them impractical for production.
Continue reading »Garbage Collection: G1GC, ZGC, Epsilon, and AppCDS
GC Changes Across Java 9–11 Release Change JEP Java 9 G1GC becomes the default GC JEP 248 Java 9 Unified GC logging (-Xlog:gc*) JEP 271 Java 10 Parallel Full GC for G1 JEP 307 Java 10 Application Class-Data Sharing (AppCDS) JEP 310 Java 11 Epsilon: No-Op GC JEP 318 Java 11 ZGC: Scalable Low-Latency GC (experimental) JEP 333 G1GC as Default (JEP 248, Java 9) G1 (Garbage-First) replaced Parallel GC as the default on systems with ≥2 CPUs and ≥2 GB heap.
Continue reading »HTTP Client API (JEP 321): HTTP/2, Async, and Authentication
Why a New HTTP Client? HttpURLConnection — Java’s HTTP API since Java 1.1 — has deep design problems: Mutable shared state makes it error-prone in multithreaded code No built-in HTTP/2 support No built-in async; non-blocking requires manual thread management Clunky API: setDoOutput(true), getOutputStream(), connect() in sequence No support for reactive streams JEP 321 (Java 11) standardised the HTTP Client API that was incubating since Java 9. The new API lives in java.
Continue reading »Java 11 Overview: The Road from Java 8 Through Java 9, 10, to LTS
Why Java 11 Matters Java 8 was released in March 2014. It dominated enterprise Java for nearly a decade, but it misses a decade’s worth of language improvements, API modernisation, JVM advances, and security hardening. Java 11 (September 2018) is the first Long-Term Support release after Java 8, and it packages three releases of evolution into a single supported baseline. For most teams the question is not whether to upgrade, but how.
Continue reading »Java 11 Production Checklist and Performance Best Practices
Production Readiness Checklist [ ] JDK distribution chosen and version pinned [ ] Heap and Metaspace sized correctly [ ] GC selected and tuned for your workload [ ] Container-aware JVM flags set [ ] AppCDS archive built for faster startup [ ] JFR always-on recording configured [ ] GC logging enabled with rotation [ ] Security-related algorithms locked down [ ] Thread and connection pool sizes verified [ ] JVM exit flags prevent silent crashes Baseline JVM Flags for Java 11 Start with these flags and tune from here:
Continue reading »Migrating to Java 11: From Java 8 — Step by Step
Migration Overview Migrating from Java 8 to Java 11 is the most common Java upgrade scenario. The migration has two distinct phases: Make it compile and run — fix incompatibilities introduced by Java 9–11 Modernise the code — adopt var, List.of(), String.isBlank(), and other new APIs Phase 1 is mandatory and blocks the upgrade. Phase 2 is optional and can happen incrementally. This guide focuses entirely on Phase 1. The 10-Step Migration Checklist [ ] 1.
Continue reading »Migrating to Java 17: From Java 8 and Java 11 — Step by Step
Why Migrate to Java 17? Java 17 is the current recommended enterprise LTS. Key reasons to migrate now: Spring Boot 3.x requires Java 17 — the entire Spring ecosystem is moving here Java 11 extended support ends around 2026 depending on your vendor Java 8 mainstream support ended in 2019; extended support ended 2030 for Oracle JDK but active vulnerability exposure is increasing Language features: Records, Sealed Classes, Text Blocks, Pattern Matching, Switch Expressions — all available in Java 17 Security: Strong JDK encapsulation closes years of internal API exposure used in exploits Recommended Migration Path Java 8 → Java 11 → Java 17 Do not jump directly from Java 8 to Java 17 in one step if your codebase is large or has many third-party dependencies.
Continue reading »Migrating to Java 21: From Java 8, 11, and 17 — Step by Step
Why Migrate Now? Java 21 is the current Long-Term Support (LTS) release, and it is the most feature-rich LTS since Java 8. LTS releases receive security patches and bug fixes for years. Java 11, the previous widely-used LTS, reached its extended support window end depending on your vendor. Java 8 mainstream support ended in 2019. More concretely, Java 21 brings: Virtual Threads — drop-in replacement for platform threads, enabling massive concurrency without reactive rewrites Pattern Matching for switch and records — eliminating entire categories of verbose, error-prone instanceof/cast chains Sequenced Collections — a unified API for ordered collection types Generational ZGC — sub-millisecond GC pauses at any heap size These are not incremental improvements.
Continue reading »