Skip to main content

Command Palette

Search for a command to run...

Stable Values und Immutability in Java: Eine Klarstellung

Updated
7 min read

Im Oktober 2025 hatte ich die Gelegenheit, bei der betterCode Java 2025 einen Vortrag zum Thema "Stable Values - JVM-optimierte Immutability" zu halten. Der Vortrag drehte sich um JEP 502 "Stable Values" und wie dieses Feature die Art und Weise verändert, wie wir mit verzögerter Unveränderlichkeit in Java umgehen können.

Der Abstract zum Vortrag

In der Java-Entwicklung kennt man das Dilemma: Daten sollen immutable sein, doch final -Felder erzwingen sofortige Initialisierung, was den Anwendungsstart verlangsamen kann. Nicht- final -Felder erlauben flexibles Timing, erschweren aber die Handhabung bei konkurrierenden Zugriffen und verhindern JVM-Optimierungen. Oft entstehen umständliche Muster.
JEP 502 "Stable Values" bietet eine Lösung für verzögerte Unveränderlichkeit. Ein Stable Value speichert einen Wert, der später und garantiert nur einmal gesetzt wird, oft bei Bedarf. Die Vorteile sind klar: Verbesserter Anwendungsstart durch Lazy Loading. Die JVM kann Stable Values wie final -Felder optimieren, was zu besserer Performance führt. Sie ermöglichen flexibles, sicheres und performantes Coden.
Mein Vortrag beleuchtete, wie Stable Values die Lücke schließen, gängige Muster ersetzen können und Code vereinfachen.

Das Feedback

Nach dem Vortrag erhielt ich konstruktives Feedback, auf das ich gerne näher eingehen möchte:
"Immutability und Stable Values (bzw. Lazy Values) sind zwei unterschiedliche Dinge. Stable Values sind ein besseres final , während Immutability wirklich fordert, dass das ganze Objekt nicht veränderbar ist, d.h. da gibt es keine Setter (die neue Time-API macht das schön vor), was optimal für funktionale Programmierung ist (Stichwort: Monaden). Ein Objekt, das irgendwo als Stable Value initialisiert wird, kann lediglich nicht mehr ersetzt werden. Mit einem existierenden Setter ist es aber jederzeit veränderbar, d.h. nichts ist mit Immutability. Hier verfehlt der Vortrag das Thema…"

Meine Antwort und Klarstellung

Diese Anmerkung bietet eine wertvolle Gelegenheit zur Klärung. Ich möchte dazu ein paar wichtige Punkte herausarbeiten:

Das final-Keyword als Baustein

In meinem Vortrag habe ich versucht deutlich zu machen, dass das final-Keyword in Java ein wichtiger Baustein für Immutability ist – aber eben nur ein Baustein, kein vollständiges Konzept. Das final-Keyword hat zwei wesentliche Einschränkungen:
Erstens muss ein als final deklariertes Klassenfeld spätestens im Klassen-Konstruktor initialisiert werden. Es gibt keine Möglichkeit, dies später zu tun.
Zweitens sind final-Felder nicht wirklich "final" im Sinne von konstant oder unveränderbar, wenn sie auf Instanzen von mutable Klassen verweisen. Diesen Punkt habe ich in meinem Vortrag ausdrücklich angesprochen.

Was Stable Values bieten

Mit StableValue, das in Java 25 als Preview eingeführt wurde (und wahrscheinlich ab Java 26 zu LazyConstant wird), haben wir nun eine neue Möglichkeit: wir können einen Wert speichern, der nicht mehr verändert werden kann, sobald er einmal gesetzt wurde. Was dieser "Wert" ist, ist erstmal nicht entscheidend, es kann sowohl eine Zahl, ein String als auch eine Referenz auf ein Objekt sein. Der entscheidende Unterschied: Der Zeitpunkt, wann dieser Wert gesetzt wird, ist flexibel thread-safe und muss nicht zwangsläufig im Konstruktor geschehen. Zudem bieten StableValues auch dieselben JVM-Optimierungsmechanismen wie das final-Keyword (Stichwort: Constant Folding)

Der Unterschied zur vollen Immutability

Natürlich hat der/die Feedback-Geber/in recht: Wenn man eine Instanz einer mutable Klasse als Wert in einem StableValue speichert, kann man diese Instanz auch wieder auslesen und darauf dann setter-Methoden aufrufen. Insofern ist der Inhalt des im StableValue referenzierten Objekts dann veränderbar. StableValue macht (wie auch final) nur die Referenz immutable. Für wirkliche Immutability braucht man also auch immutable Klassen.

Ein Baustein, kein Allheilmittel

StableValue bietet einen weiteren Baustein, um mit Immutability in Java zu arbeiten. Wenn man konsequent immutable programmieren möchte, wird das in Java immer mit zusätzlichem Aufwand verbunden sein. Aber die Sprache entwickelt sich weiter und bietet immer mehr Hilfsmittel – von Records über Sealed Classes bis hin zu Stable Values – um idiomatischen, sicheren und performanten Code zu schreiben.

Fazit

Ich hoffe, ich konnte mit dieser Klarstellung zeigen, dass mein Vortrag nicht den Anspruch hatte, Stable Values als vollständige Lösung für Immutability darzustellen, sondern als wichtigen Baustein, der eine Lücke im bisherigen Java-Ökosystem schließt. Die Diskussion zeigt, wie wichtig es ist, zwischen verschiedenen Ebenen von Immutability zu unterscheiden: die Unveränderlichkeit von Referenzen und die Unveränderlichkeit von Objektzuständen.

Ich freue mich über weitere Anmerkungen und Kommentare zu diesem Thema!


English version:

Stable Values and Immutability in Java: A Clarification

In October2025 I had the opportunity to give a talk at betterCode Java 2025 on the topic "Stable Values - JVM-Optimized Immutability." The presentation focused on JEP 502 "Stable Values" and how this feature transforms the way we handle deferred immutability in Java.

The Talk Abstract

In Java development, we know the dilemma: data should be immutable, but final fields require immediate initialization, which can slow down application startup.
Non-final fields allow flexible timing but complicate handling with concurrent access and prevent JVM optimizations. This often leads to cumbersome patterns.
JEP 502 "Stable Values" offers a solution for deferred immutability. A Stable Value stores a value that is set later and guaranteed to be set only once, often on demand.
The advantages are clear: improved application startup through lazy loading. The JVM can optimize Stable Values like final fields, resulting in better performance. They enable flexible, safe, and performant coding.
My talk examined how Stable Values fill this gap, can replace common patterns, and simplify code.

The Feedback

After the talk, I received constructive feedback that I'd like to address in more detail:

"Immutability and Stable Values (or Lazy Values) are two different things. Stable Values are a better final, while immutability truly requires that the entire object be unchangeable, meaning there are no setters (the new Time API demonstrates this nicely), which is optimal for functional programming (keyword: monads). An object initialized as a Stable Value can merely not be replaced. However, with an existing setter, it remains mutable at any time, meaning there's nothing immutable about it. Here the talk misses the point..."

My Response and Clarification

This observation provides a valuable opportunity for clarification. I'd like to highlight a few important points:

The final Keyword as a Building Block

In my talk, I tried to make clear that the final keyword in Java is an important building block for immutability – but just a building block, not a complete concept. The final keyword has two significant limitations:
First, a field declared as final must be initialized no later than in the class constructor. There's no way to do this later.
Second, final fields aren't truly "final" in the sense of constant or immutable when they reference instances of mutable classes. I explicitly addressed this point in my presentation.

What Stable Values Offer

With StableValue, introduced as a preview in Java 25 (and likely becoming LazyConstant from Java 26), we now have a new capability: we can store a value that cannot be changed once it's been set. What this "value" is doesn't matter initially – it can be a number, a string, or even a reference to an object. The crucial difference: the timing of when this value is set is flexible and thread-safe, and doesn't necessarily have to happen in the constructor.
Additionally, StableValues offer the same JVM optimization mechanisms as the final keyword (keyword: Constant Folding).

The Difference from Full Immutability

Of course, the feedback provider is correct: if you store an instance of a mutable class as a value in a StableValue, you can retrieve that instance and then call setter methods on it. In this respect, the content of the object referenced in the StableValue is mutable.
StableValue makes (like final) only the reference immutable. For true immutability, you also need immutable classes.

A Building Block, Not a Panacea

StableValue offers another building block for working with immutability in Java. If you want to program consistently with immutability, it will always involve additional effort in Java. But the language continues to evolve and offers more and more tools – from Records to Sealed Classes to Stable Values – for writing idiomatic, safe, and performant code.

Conclusion

I hope this clarification demonstrates that my talk didn't claim Stable Values as a complete solution for immutability, but rather as an important building block that fills a gap in the existing Java ecosystem. The discussion shows how important it is to distinguish between different levels of immutability: the immutability of references and the immutability of object states.

I look forward to further comments and feedback on this topic!

 
 
 

Bild von Bronisław Dróżka auf Pixabay