🚀 Modern Java 17 → 25 · Advanced

Preview & incubator features in Java

--enable-preview, how features graduate (e.g. primitive patterns, structured concurrency).

🧩 The mysteryYou paste a StructuredTaskScope example into your Java 25 project and javac refuses: it's a "preview API". Not a bug, a deliberate safety catch. Here's how Java test-drives new features.

Preview features

Many new language features and APIs arrive first as preview features: fully specified, but not permanent. They're off by default: you must compile and run with --enable-preview. They may change or vanish between releases, and usually graduate after one or more rounds of feedback.

javac --release 25 --enable-preview Main.java
java --enable-preview Main

Why not finalize right away?

Once a feature is final, Java's compatibility promise makes it nearly impossible to change. Previews let real developers try the design while it can still evolve. It's not early access for paying customers, and preview code doesn't run faster: it's purely about getting feedback.

🔮 Predict it

Your turn

You compiled with --enable-preview on JDK 25. Ops runs those class files on JDK 26. What happens?

  1. They run unchanged
  2. The JVM refuses to load them
  3. They run, with a warning
Show the answer

The JVM refuses them with UnsupportedClassVersionError. Class files that use preview features are tied to the exact JDK version that compiled them, and still need the flag there, because the feature may have changed in the next release.

Incubator modules

Experimental APIs can also ship as incubator modules in the jdk.incubator.* namespace, such as the Vector API in jdk.incubator.vector. You add one with --add-modules jdk.incubator.vector. Incubating is an even earlier, looser stage than preview.

Status check: Java 25

Final: pattern matching for switch and record patterns (21), unnamed variables _ (22), flexible constructor bodies (25), scoped values (25). Still preview: structured concurrency, primitive types in patterns. Incubator: the Vector API. Check a feature's JEP status before relying on it.

⚠️ The trap

Don't guess the fix

For a "preview API" error on Java 25, the fix is to compile and run with --enable-preview (and --release 25). Upgrading to Java 26 won't help, since structured concurrency is still preview there. There's no @Preview annotation to add, and no incubator module to pull in.

💼 In the real world

Team policy

Many teams allow preview features in experiments and side projects but keep them out of production, because every JDK upgrade could break them. Trying previews early is still valuable: feedback from real code is exactly how features like records and pattern matching were shaped.

Key takeaways

  1. Preview is off by default: javac --release 25 --enable-preview
  2. Preview class files run only on that same JDK version, with the flag
  3. Still preview in 25: structured concurrency, primitive patterns
  4. Incubator APIs live in jdk.incubator.* modules (e.g. Vector API)
🤯 Did you know?

The Vector API has incubated in every release since Java 16 (ten rounds by Java 25) because it's waiting for Project Valhalla's value classes.

Practice questions

A developer pastes a StructuredTaskScope example into a Java 25 project and gets a compile error saying it's a preview API. What's the fix?

  1. Compile and run with --enable-preview (and --release 25)
  2. Add the jdk.incubator.concurrent module
  3. Upgrade to Java 26, where it's final
  4. Annotate the class with @Preview
Check your answer

Compile and run with --enable-preview (and --release 25). Preview features must be enabled explicitly at both compile time and run time. It's still a preview in Java 26 too.

Why does Java ship preview features at all instead of finalizing them right away?

  1. To gather real-world feedback while the design can still change
  2. To give paying customers early access
  3. Because preview features run faster
  4. To test new garbage collectors
Check your answer

To gather real-world feedback while the design can still change. Once a feature is final, Java's compatibility promise makes it nearly impossible to change. Previews let the design evolve based on real use first.

Next: bring an old Java 8 codebase into the modern era. What you gain, and what's been removed.