embarc logo
embarc logo

Value Objects - das nächste große Ding in Java

Falk Sippach Falk Sippach
25.09.2025

Lesezeit: 5 Minuten

Mit Project Valhalla bekommt Java ein neues Datentyp-Konstrukt: Value Objects. Sie kombinieren die Performance primitiver Typen mit der Ausdruckskraft von Objekten und ermöglichen flaches Speicherlayout, weniger Garbage Collection und stärkere Typsicherheit. In diesem Artikel schauen wir uns an, was dahintersteckt, welche JEPs den Weg ebnen und wie Value Objects die Entwicklung in Java verändern werden.

Vortragsfolien zum Thema

Download der Folien vom JUG Saxony Day am 26.09.2025

Was sind Value Objects

Einer der großen Pluspunkte von Java war und ist das statische, starke Typsystem. Es hilft, viele Fehler bereits zur Compilezeit zu entdecken und macht die Entwicklung robuster sowie effizienter. Allerdings integrieren sich die vor etwa 30 Jahren aus Performancegründen eingeführten primitiven Datentypen nicht gut mit modernen Ansätze wie Generics, Stream API oder Pattern Matching. Value Objects versprechen Abhilfe und werden die Vorteile beider Welten kombinieren. Damit können wir in Zukunft unveränderbare Datentypen entwerfen, die sich wie primitive Datentypen verhalten. Das steigert nicht nur die Performance und senkt den Speicherverbrauch, es erhöht durch das Schreiben von ausdrucksstarken Typen auch die Les- und Wartbarkeit.

Schon seit etwa 10 Jahren wird im Rahmen vom Projekt Valhalla an dieser großen Änderung des Java Typsystems gearbeitet. Daran hängen einige komplexe Fragestellungen, wie z. B. der Umgang mit Default-Werten sowie null-Values, der Umbau der Wrapper-Typen (Integer, …) und die Verwendung als generische Typisierung. Im Sommer 2024 hat Java Language Architekt Brian Goetz verkündet, dass nach der langen Zeit der Durchbruch in der Umsetzung erreicht ist. Darum wollen wir hier schauen, wie Value Classes, Null-Restricted und Nullable Types sowie erweitertes Primitive Boxing die Art und Weise verändern, wie wir in Zukunft programmieren werden.

Projekt Valhalla

Das Motto von Projekt Valhalla trifft den Kern sehr gut:

“Codes like a class, works like an int.” (State of Valhalla: Part 1: The Road to Valhalla (2021))

Das Ziel: Die Ausdrucksstärke objektorientierter Referenztypen mit der Performance primitiver Typen zu vereinen.

Da nun schon seit einer Dekade an der Idee der Value Classes in Java gearbeitet wird, sind bereits einige vorbereitende Arbeiten in den letzten Java-Releases ausgeliefert worden:

  • JEP 181 (Java 11) - Nest-Based Access Control: Ermöglicht inneren und äußeren Klassen effizienteren Zugriff auf private Member. Grundlage für zusammengesetzte Value Types.
  • JEP 309 (Java 11) - Dynamic Class-File Constants: Neue Bytecode-Konstante CONSTANT_Dynamic, Berechnung erst beim ersten Zugriff - erlaubt Lazy Initialization.
  • JEP 334 (Java 12) - JVM Constants API: Typsichere Repräsentation von Bytecode-Konstanten im Java-Code.
  • JEP 371 (Java 15) - Hidden Classes: Klassen zur Laufzeit erzeugen, die aber nicht referenzierbar sein sollen. Hilft Frameworks und für temporäre Strukturen von Value Classes.
  • JEP 390 (Java 16) - Warnings for Value-Based Classes: Warnungen, wenn so genannte wertbasierte Klassen wie Integer, LocalDate oder Optional falsch genutzt werden. Diese Klassen sollen in der Zukunft in echte Value Classes migriert werden und die falsche Benutzung in Legacy Code würde dann zu Problemen führen.

Arten von Speicherbereichen in Java

Das Java-Memory-Model unterscheidet strikt zwischen primitiven Datentypen, die im Stack abgelegt sind und Objekten, deren Referenz ebenfalls auf dem Stack, das eigentliche Objekt dann aber im Heap abgelegt ist. Diese Referenztypen benötigen für Meta-Informationen mehr Speicherplatz und sind im Heap auch deutlich weiter weg von ihrer Verarbeitung in der CPU abgelegt. Dadurch dauern Zugriffe länger und die Performance leidet. Dafür sind Referenztypen selbst definierbar, so dass wir benutzerdefinierte, gut les- und wartbare Typen für unsere fachlichen Anforderungen erstellen können.

int i = 12345;          // liegt direkt auf dem Stack
Point p = new Point(1,1); // Referenz auf ein Objekt im Heap

Abbildung 1: zwei Variablen: primitiver (i) und Referenzdatentyp (p)

Value Classes

Eine Value Class lässt sich einfach mit dem neuen Schlüsselwort value analog zu normalen Klassen bzw. Records anlegen.

value class PointValue { .. }

value record PointRecordValue(int x, int y);

PointRecordValue[] points = new PointRecordValue[10];

for (int i = 0; i < 10; i++) {
    points[i] = new PointRecordValue(i, i);
}

Es gelten aber einige Einschränkungen:

  • Value Classes und Felder sind final, dürfen aber von Interfaces ableiten
  • Value Classes haben keine Identität
  • für == und hashCode werden die Felder verwendet
  • kein synchronized erlaubt
  • JVM kann (muss aber nicht) Speicherlayout und Performance optimieren

Value Classes können aber auch ganz normale Instanzmethoden enthalten, die Verhalten des Objekts kapseln:

public value record Point(int x, int y) {   
  public Point moveBy(int dx, int dy) { 
    return new Point(x + dx, y + dy); } 
}

Hinweis

Value Classes waren zum Erscheinungszeitpunkt dieses Blog-Posts noch nicht Teil von Java. Voraussichtlich mit dem OpenJDK 28 wird ein erster Teil im März 2027 als Preview erscheinen. Die Arbeiten zur Finalisierung und an weiteren Themen wie Null-Restricted and Nullable Types sowie Enhanced Primitive Boxing werden sich noch über mehrere Jahre hinziehen. Im JEP 401 können aber jetzt schon weitere Beispiele und der aktuelle Status nachgelesen werden.