Note: JEP 507 is a preview feature in Java 25 (3rd preview). Enable it with --enable-preview at compile and runtime. It is expected to finalize in Java 26 or 27. The Asymmetry in Pattern Matching Java 21 gave us pattern matching for switch and instanceof. It is a great feature — but it had a glaring asymmetry: it only worked with reference types. Object obj = 42; // Java 21: works fine if (obj instanceof Integer i) { System.
Continue reading »Preview
9 posts in this section
Structured Concurrency (JEP 505): Preview 5 — What Changed?
Note: JEP 505 is a preview feature in Java 25 (5th preview). Enable with --enable-preview. The API has been stable for several rounds and is expected to finalize in Java 26. The Problem with Unstructured Concurrency Classic Java concurrency with ExecutorService is unstructured: you submit tasks, and those tasks have no formal relationship with the code that submitted them. This causes three recurring problems: Problem 1: Partial failure leaves orphaned tasks ExecutorService exec = Executors.
Continue reading »Foreign Function & Memory API (JEP 442): Calling Native Code Without JNI
Preview Feature in Java 21 — Finalized in Java 22 (JEP 454). The API shown here is the Java 21 preview version; it is nearly identical to the final API. Why Replace JNI? Java Native Interface (JNI) has been the standard way to call native code since Java 1.1. It works but is notoriously painful: Requires writing C wrapper code for every native call Native method signatures must exactly match Java declarations (or you get silent crashes) Memory management is manual — leak native memory once and you have a slow memory leak JNI calls disable JIT optimizations around the call site Debugging native crashes through JNI is extremely difficult The Foreign Function & Memory (FFM) API replaces all of this: call native functions directly from Java, manage native memory safely with automatic lifetime management, and do it without writing a single line of C.
Continue reading »Pattern Matching for switch (JEP 406): Type Dispatch in switch (Preview)
Preview Feature in Java 17 (JEP 406 — First Preview). Requires --enable-preview. This feature evolved through Java 18 (JEP 420), Java 19 (JEP 427), Java 20 (JEP 433), and was finalized in Java 21 (JEP 441). The Java 21 final version has minor syntax differences from this Java 17 preview — documented below. Enabling Preview Features Pattern matching for switch requires --enable-preview in Java 17. Add to your build tool:
Continue reading »Scoped Values (JEP 446): Thread-Safe Context Without ThreadLocal
Preview Feature — Requires --enable-preview at compile and runtime. The ThreadLocal Problem at Scale ThreadLocal has been the standard way to pass context (request ID, user session, database transaction) implicitly through a call stack without threading it through every method signature. It works well with a few hundred platform threads. With virtual threads, it breaks down. Problem 1 — Memory overhead with inheritance When you create a child thread with InheritableThreadLocal, Java copies the thread-local map from parent to child:
Continue reading »Structured Concurrency (JEP 453): Safe, Readable Concurrent Code
Preview Feature — Requires --enable-preview at compile and runtime. The API stabilized significantly from Java 21 through 24 and will be finalized in a future release. The Unstructured Concurrency Problem When you submit tasks to an ExecutorService, the tasks are logically related but structurally unconnected — the executor doesn’t know they belong together: // Unstructured concurrency — looks simple, hides serious problems ExecutorService executor = Executors.newCachedThreadPool(); Future<Order> orderFuture = executor.
Continue reading »Unnamed Classes and Instance Main Methods (JEP 445): Java for Scripts and Beginners
Preview Feature — Requires --enable-preview at compile and runtime. The Boilerplate Problem Teaching Java to a beginner means explaining class declarations, access modifiers, static, and String[] before they can print “Hello, World!”: // Traditional Java — 4 concepts before printing one line public class HelloWorld { public static void main(String[] args) { System.out.println("Hello, World!"); } } Every word carries meaning, but that meaning is irrelevant until the student understands OOP, the JVM class model, and program entry points.
Continue reading »Unnamed Patterns and Variables (JEP 443): Writing Intent-Clear Code
Preview Feature — Requires --enable-preview at compile and runtime. The _ identifier was reserved in Java 9; this JEP gives it formal semantics. The Problem: Forced Naming of Unused Things When pattern matching, you often care about only some components of a matched structure. But the syntax forces you to name everything: record Point(int x, int y) {} record ColoredPoint(Point point, String color) {} record Box(ColoredPoint cp, int weight) {} // You only care about the color — but must name everything else if (obj instanceof Box(ColoredPoint(Point(int x, int y), String color), int weight)) { System.
Continue reading »Vector API (JEP 448): SIMD Computation in Java
Preview Feature in Java 21 — The Vector API has been in preview since Java 16 (JEP 338). JEP 448 is the sixth preview iteration in Java 21. The API is stable and production-usable with --enable-preview; finalization is pending Project Valhalla value types. What Is SIMD and Why Does It Matter? Modern CPUs can perform the same arithmetic operation on multiple data values in a single instruction. This is called SIMD — Single Instruction, Multiple Data.
Continue reading »