4 Minuten
Project Valhalla: Value Classes und was sie für Java bedeuten
Einführung
Project Valhalla ist eines der am längsten laufenden OpenJDK-Projekte. Nach über zehn Jahren Entwicklung gibt es jetzt konkrete Fortschritte: mit JEP 401 (Value Classes and Objects) liegt ein Early-Access-Build auf Basis von JDK 27 vor. Die Grundidee ist einfach, aber die Auswirkungen auf die Java-Plattform sind gravierend: Objekte, die sich wie primitive Typen verhalten.
Das Problem
In Java gibt es zwei Arten von Typen: Primitive (int, double, boolean) und Referenztypen (alles andere). Primitive sind schnell und effizient im Speicher, unterstützen aber keine Methoden, kein Null und keine Vererbung. Referenztypen haben all das, aber jeder Zugriff geht über eine Referenz im Heap — das kostet Speicher (Header) und Performance (Pointer-Dereferenzierung, Cache-Misses).
// Primitive: 8 Bytes, direkt im Speicher, kein Overhead
int x = 42;
// Referenztyp: 16 Bytes Header + 8 Bytes Referenz = 24 Bytes pro Objekt
// Plus Pointer-Indirektion bei jedem Zugriff
Point p = new Point(1, 2);
Für Datenmodelle wie Punkte, komplexe Zahlen,货币werte oder Temperaturwerte ist das ineffizient. Du willst die Abstraktion eines Objekts, aber die Performance eines primitiven Typs.
Value Classes: Codes like a class, works like an int
Value Classes lösen dieses Problem. Ein Value Class wird mit dem value-Modifier deklariert:
public value class Point {
private final double x;
private final double y;
public Point(double x, double y) {
this.x = x;
this.y = y;
}
public double distanceTo(Point other) {
double dx = this.x - other.x;
double dy = this.y - other.y;
return Math.sqrt(dx * dx + dy * dy);
}
}
Die Regeln: nur final-Felder, keine Objekt-Identität. Zwei Value Objects sind gleich, wenn alle Felder gleich sind. Vergleichbar mit Records, aber mit Laufzeit-Optimierungen durch die JVM.
Laufzeit-Optimierungen
Das Besondere an Value Objects sind die JIT-Optimierungen:
Heap Flattening
Value Objects, die als Felder oder Array-Elemente gespeichert werden, werden direkt inline im Speicher abgelegt — ohne separate Objekt-Allocierung und ohne Pointer.
// Ohne Value Classes: Array von Point-Referenzen
Point[] points = new Point[1000]; // 1000 Referenzen + 1000 separate Objekte
// Mit Value Classes: Array mit flachen Point-Daten
value Point[] points = new value Point[1000]; // Daten liegen direkt hintereinander
Das verbessert die Cache-Lokalität deutlich und reduziert den Speicherverbrauch.
Scalarization
Wenn ein Value Object in einem Hot Path genutzt wird, kann der JIT Compiler es komplett eliminieren und die Feldwerte direkt in Registern halten. Keine Objekt-Allocierung, kein GC-Druck.
Was bedeutet “keine Objekt-Identität”?
Value Objects haben keine Identität im Sinne von ==. Es gibt keine Monitor-Operationen (synchronized, wait, notify), und sie können nicht als Lock verwendet werden. Zwei Value Objects mit gleichen Feldwerten sind nicht unterscheidbar:
value Point a = new Point(1.0, 2.0);
value Point b = new Point(1.0, 2.0);
// a == b ist undefiniert (keine Identität)
// a.equals(b) vergleicht die Feldwerte → true
Das ist analog zu primitiven Typen: zwei int-Variablen mit Wert 42 sind ebenfalls nicht “identisch”.
Kompatibilität und Migration
Die JEP 401 Early-Access-Builds sind auf jdk.java.net/valhalla verfügbar. Wer experimentieren will:
- Java-Code mit
value-Modifier kompilieren:javac --enable-preview - Ausführen:
java --enable-preview - Bestmögliche Performance: alle Klassen, die Value Classes referenzieren, mit
--enable-previewkompilieren
Bekannte Einschränkungen:
java.io.Serializablefunktioniert noch nicht vollständig mit Value Objects- Reflection (
Field.setAccessible) hat Einschränkungen - Generische APIs mit polymorphen Variablen können nicht voll optimiert werden
Was Value Classes für bestehenden Code bedeuten
Viele bestehende Klassen lassen sich potenziell zu Value Classes migrieren: java.awt.Point, java.time.LocalDate, java.util.Optional, Records ohne Identity. Die Migration ist oft kompatibel, aber es gibt Verhaltensänderungen bei ==, synchronized und Serialisierung, die beachtet werden müssen.
Ausblick
Value Classes werden voraussichtlich als Preview in JDK 27 erscheinen. Die finale Version wird davon abhängen, wie das Feedback aus den Early-Access-Builds ausfällt. Bis dahin gilt: ausprobieren, Feedback geben, und die Entwicklung beobachten.
Die Vector API (aktuell 11. Inkubation) wartet ebenfalls auf Value Classes, da sie von den Performance-Eigenschaften profitieren wird. Valhalla ist der Schlüssel für mehrere langfristige Java-Verbesserungen.
Fazit
Value Classes sind eine der wichtigsten Änderungen an der Java-Plattform seit Generics. Sie schließen die Lücke zwischen primitiven Typen und Objekten und ermöglichen effiziente Datenmodellierung ohne den Overhead von Referenztypen. Wer datenintensive Anwendungen schreibt, sollte die Early-Access-Builds jetzt testen und Feedback an das Valhalla-Team senden.