Value classes are a super neat way to improve type safety in your code without paying the price of object creation at runtime.
In many programming languages, especially on the JVM, it’s easy to pass around raw primitives or strings like IDs, tokens, etc. But doing that often leads to bugs like accidentally swapping a userId
with an orderId
.
Enter: Value Classes
A value class wraps a single primitive or object but is treated like the original value at runtime — meaning: no extra memory cost, but you still get strong typing at compile time.
class UserId(val value: String) extends AnyVal
def getUser(id: UserId): String = s"User: ${id.value}"
val uid = new UserId("abc123")
println(getUser(uid))
Why I Like It
- Clean type distinction
- No runtime overhead
- Makes APIs self-documenting