Living with preview and incubator features

Java 23 Course · lesson 15 of 15 · 6 min read

What --enable-preview commits you to, and why it is not for production.

Open this lesson in the learning hub

Key points

  • A preview feature is complete but not permanent. It may change or be withdrawn in the next release - string templates were previewed in 21 and 22, then removed in 23.
  • Preview class files are marked with the exact JDK version that produced them, and they will refuse to run on any other version, even a newer one.
  • That is deliberate: it stops preview bytecode leaking into long-lived artefacts. It also means every JDK bump forces a full recompile of that code.
  • Incubator modules are weaker still - the Vector API has incubated for years. They live in jdk.incubator.* and need an explicit --add-modules.
  • The practical rule: preview features belong in experiments and internal tools, never in a library other people depend on, and never in an artefact you cannot rebuild on demand.
  • If you do adopt one, isolate it in a single module with a documented fallback, so a withdrawal is a contained change rather than a rewrite.

Example

# Compiling and running with a preview feature - both flags are required.
$ javac --release 23 --enable-preview Main.java
$ java --enable-preview Main

#   Forgetting it at runtime:
#   Preview features are not enabled for Main (class file version 67.65535).
#   Try running with '--enable-preview'

# The 65535 minor version is the marker. It PINS the class file to that
# exact JDK - a JDK 23 preview class will not run on JDK 24, by design.

---
# Gradle
tasks.withType(JavaCompile).configureEach {
    options.compilerArgs += '--enable-preview'
}
tasks.withType(Test).configureEach { jvmArgs '--enable-preview' }
tasks.named('bootRun') { jvmArgs '--enable-preview' }
#   Miss any one of these and it fails only in that context.

---
# Incubator modules need an explicit --add-modules:
$ javac --add-modules jdk.incubator.vector Main.java
$ java  --add-modules jdk.incubator.vector Main
#   WARNING: Using incubator modules: jdk.incubator.vector

---
# THE STRING TEMPLATE LESSON:
#
#   JDK 21  preview      teams adopted it
#   JDK 22  second preview
#   JDK 23  REMOVED      that code no longer compiles at all
#
# Not a warning, not a deprecation - removed. That is what preview means,
# and it is exactly why it does not belong in a shipped library.

# A defensible policy:
#   production service      no preview features
#   published library       absolutely no preview features
#   internal tooling        acceptable if you can rebuild on demand
#   experiments and spikes  the intended audience

Preview bytecode is pinned to the exact JDK that built it and can be withdrawn outright - string templates were, in one release.

This is a reading copy. The full lesson — with the visual explainer, the interactive lab and a Run button for the code — lives in the Java 23 Course course, and every lesson in it is listed on the Java 23 Course contents page.