Records =?utf-8?Q?=E2=80=94_?=Dealing with nullable values
Arash Shahkar
arash.shahkar at gmail.com
Sat Dec 14 22:31:12 UTC 2019
In my example, gender can be left undefined, but not name. Dropping requireNonNull(gender) from the compact constructor works, but leaves the accessor for gender returning null (possibly).
What I’d like to achieve is to have the accessor for gender return Optional<Gender>, to clearly communicate that it might be null. I have found this pretty common, and using this pattern has helped a lot.
I was wondering if my “workaround” to be able to use records and drop Lombok for these cases is a big no-no.
On Dec 14, 2019, 5:16 PM -0500, Brian Goetz <brian.goetz at oracle.com>, wrote:
> No, that would not be a good idea. If you find yourself using Optional
> for a method parameter, or a field type, or a record component type,
> you've almost certainly gone Optional-crazy. It's a common, but
> curable, disease.
>
> What you want to do is this:
>
> record Foo(String name, Gender gender) {
> Foo {
> requireNonNull(name);
> requireNonNull(gender);
> }
> }
>
> The `Foo { ... }` is a _compact constructor_, which is a constructor
> whose signature is the same as that of the record, and which
> automatically handles the `this.x = x` boilerplate for you. This is
> where you put argument validation / normalization.
>
>
> On 12/14/2019 5:01 PM, Arash Shahkar wrote:
> > Hi,
> >
> > I’ve been using Lombok for quite a while now to automatically generate boilerplate code for "data carrier" classes. However, a pattern I really like and have found to work very well is to verify non-nullity of all the fields that must not be null, and return an Optional<Field> from the accessor of a field if it’s allowed to have a null value. Consider:
> >
> > @lombok.Value
> > class Person {
> >
> > String name;
> > Gender gender;
> >
> > Person(String name, Gender gender) { … } // customize the constructor, verifying that name is defined and valid
> >
> > Optional<Gender> getGender() { // customize the accessor for gender, to make sure calling code deals with the possibility of gender being null
> > return ofNullable(gender);
> > }
> > }
> >
> > Doing a similar thing with records is not possible, due to the fact that the accessor for gender has to exactly return a Gender. With the current specification for records, the only option is to do:
> >
> > record Person(String name, Optional<Gender> gender) {
> > …
> > }
> >
> > Is this considered good practice? Do you suggest any alternatives?
>
More information about the amber-dev
mailing list