Valhalla tilt type safety en performance naar een hoger niveau
Domeingestuurde types met Java-prestaties: hoe Project Valhalla alles verandert
Heb je ooit een domeinmodel in Java opgezet en meteen tegen de grenzen van de taal aan gelopen? Je wilt een PositiveInt maken die nooit negatief kan zijn, maar zodra je in een hete lus terechtkomt, vallen de wrapper-objecten om. Ze kosten geheugen en vertragen alles.
Project Valhalla lost dat op.
Het oude probleem: wrappers kosten te veel
Een eenvoudige wrapper rond een int neemt op HotSpot al snel 16 bytes in beslag. Plaats je er een miljoen van in een array, dan krijg je niet de waarden zelf, maar verwijzingen naar aparte objecten. Elke toegang betekent een pointer-dereference en een mogelijke cache-miss.
Daardoor werkten domein-specifieke types alleen goed aan de rand van je applicatie. In de kritieke paden schakelde je terug naar primitieve types om snelheid te behouden, en daarmee verdween ook de typeveiligheid.
Value Classes: veiligheid zonder overhead
Met Java 27 Early Access komt de value modifier. Value classes hebben geen identiteit, net als primitieve types. De JVM mag ze dus plat in het geheugen leggen: in arrays, in velden van objecten of zelfs in registers.
public value class PositiveInt {
private final int value;
public PositiveInt(int value) {
if (value <= 0) {
throw new IllegalArgumentException("must be positive: " + value);
}
this.value = value;
}
public int value() {
return value;
}
}
De constructor en de validatie blijven intact. Alleen de representatie verandert. De JVM slaagt erin de 4 bytes data zonder objectheader in te bedden.
Meer dan één veld
Value classes werken ook als ze meerdere waarden bevatten. Stel je een Coordinate voor die een Latitude en Longitude bevat. In een traditionele class krijg je drie lagen aan verwijzingen. Een value class slaat beide double-waarden direct naast elkaar op zonder pointers.
Dat scheelt enorm bij grote volumes geografische data, zoals in mapping- of weersystemen.
Domeinmodellen zonder prestatieverlies
Voor domeinregistratie kun je nu DomainName en Tld als value classes definiëren. Validatie gebeurt nog steeds, maar je mag ze daarna door je DNS-pipeline sturen zonder dat ze extra geheugen of cache-misses veroorzaken.
public value class DomainName {
private final String value;
public DomainName(String value) {
if (!isValidDomain(value)) {
throw new IllegalArgumentException("Invalid domain: " + value);
}
this.value = value;
}
}
Compile-time controle met F-bounded generics
Met F-bounded generics kun je nu Probability en Price veilig implementeren zonder dat je ze per ongeluk kunt vergelijken. De compiler voorkomt dat al. Tot voor kort was dat alleen interessant als je de overhead accepteerde. Value classes maken het ook praktisch.
Wat dit betekent voor je architectuur
- Boundary validation hoeft niet meer te botsen met hot-path performance
- Typeveiligheid reikt nu van de API tot in de kern van je code
- Domain-driven design wordt zowel veilig als snel
Je kunt zakelijke regels in je types stoppen en de JVM laten zorgen voor de rest.
Toekomstperspectief
Project Valhalla zit nog steeds in preview, maar de trend is duidelijk. Zodra value classes in een LTS-versie zitten, zullen ze standaard worden in serieuze Java-architecturen.
Begin alvast te kijken waar je nu nog terugvalt naar primitieve types. Daar zitten precies de plekken waar value classes het verschil kunnen maken.