I really like the addition of records in Java 14, at least as a preview feature, as it helps to reduce my need to use lombok for simple, immutable "data holders".
A record comprises attributes that primarily define its state. The derivation of the accessors, constructors, etc is completely based on this state of the records.
Now in your example, the state of the attribute value is null, hence the access using the default implementation ends up providing the true state. To provide customized access to this attribute you are instead looking for an overridden API that wraps the actual state and further provides an Optional return type.
Ofcourse as you mentioned one of the ways to deal with it would be to have a custom implementation included in the record definition itself
record MyClass(String id, String value) {
Optional getValue() {
return Optional.ofNullable(value());
}
}
Alternatively, you could decouple the read and write APIs from the data carrier in a separate class and pass on the record instance to them for custom accesses.
The most relevant quote from JEP 384: Records that I found would be(formatting mine):
A record declares its state -- the group of variables -- and commits to an API that matches that state. This means that records give up a freedom that classes usually enjoy -- the ability to decouple a class's API from its internal representation -- but in return, records become significantly more concise.