Optional in Lombok
Asked Answered
G

1

58

I have a class called Address which looks like this:

@Value
class Address {

   @NotNull String userId;
   @NotNull String line1;
   String line2;

   private Address(Builder b) {
      // copy everything from builder
   }

   // override getter for line2 so that it returns Optional<String>
   public Optional<String> getLine2() {
      return Optional.ofNullable(this.line2);
   }

   // and a Builder
   public static class Builder {
     // builder methods
   }
}

Here I am forced to write Builder and a Getter because, if I want to return an Optional while using Lombok, I will have to declare line2 as Optional<String>. And that will generate a builder method which accepts Optional<String>!

Is there any other way to use lombok with Optional?

Gorizia answered 28/7, 2015 at 8:12 Comment(0)
T
8

The answer is no, and it probably never will.

You're probably doing it wrong :-) Optional is not a replacement for null nor a fancy way to prevent NullPointerException. It is to indicate that the question is unanswerable, like: what is the average age of an empty list of persons.

Optionals should never be passed on, but unboxed by the calling code as soon as possible.

See also https://www.voxxed.com/blog/2015/01/embracing-void-6-refined-tricks-dealing-nulls-java/

Since these scenarios are just a handful, and Lombok likes to enable programmers to write better code, I don't expect there will ever be support for it in Lombok.

Disclosure: I am a Lombok developer.

Trollope answered 28/7, 2015 at 11:25 Comment(30)
I really appreciate you answering this question! Thanks! I am aware of this philosophy of not using Optional as a replacement of null. And that it will an over use of Optional if used in getters. But then there is another, more convenient, philosophy of Google Guava's developers, which allows you to use Optional to replace nullGuava's Optional So, I personally think that lombok shld stay neutral and provide the support for autoOptional, and leave whether to use it or not to the programmersGorizia
We can always add features, but we really try to focus on the most important features first. This is in our opinion not one of them. We haven't encountered this pattern a lot.Trollope
There really are arguments for having Optional in fields and getters. It can be a great replacement for a lot of places where you'd use null, but not trying to mimic null checks with isPresent.Distraction
Hey @RoelSpilker ! Since Lombok already is opinionated in a way (e.g @NonNull will add a null check in the generated constructor), I believe having the ability to have getters that return Optional is a pretty interesting feature. Can I contribute somehow?Stesha
I mean that the generated getters would look like the code sample here and would be added via something like @Getter( optional = true ).Stesha
Definitely a big YES for @Getter( optional = true ) it would make me very happy.Benevolent
"Optional is not a replacement for null nor a fancy way to prevent NullPointerException" < that's just what Java architects say not to scare imperative programmers with the fact that they have introduced a functional (pseudo)monad into Java. Optional is a construct that allows for null-free code and Java can be written in functional way. Just check out Javaslang.Artamas
@Egregore just a quick note, it's called vavr these days (;Mark
I'm well aware of that fact @Mark :)Artamas
@roel-spilker Isn't it will be convenient to have getters which not return an Optional but use it to return empty value if in case of null? For example when iterating over empty Collection nothing happens, but I will get null pointer if collection is null.Stoss
@RoelSpilker Why not a @Getter(optional = true) that generates Optional return type in getters for the fields that are nullable? i.e. those that are not marked with @NonNull?Stagnate
"Optionals should never be passed on, but unboxed by the calling code as soon as possible." - why?Holarctic
"It is to indicate that the question is unanswerable, like: what is the average age of an empty list of persons." Do you have a source for this idea? More common application is: find element in collection which returns optional (it is there, or not) and operate on it using a map() function. The javadoc specify Optional as: " container object which may or may not contain a non-null value.", which I read exactly as 'a replacement for a null value'.Holarctic
I think the arguments about not passing Optionals around are based in the fact that Optional itself it is not setializable and it was deliberately designed this way to avoid using it that way if I am not wrong. That's why the reccommendation is against class members of type Optional. But on contrary I can see use cases where the return of a getter can box the field in an optional, that's why I also would like the Lombok optional getter. P.S. vavr (a great Java lib that provides functional programming constructs) Option it is serializable!Stagnate
@krund For the case of types which have a semantic equivalent (such as the empty string or the empty list), you should use the 'empty value' as early as you can in the chain. The field ITSELF should contain "" or List.of() or whatnot; the fix is NOT to make lombok deal with a field that could be either "" or null. lombok's Builder supports this via default values.Bacardi
lombok developer here: This is a far too complex issue for a stackoverflow issue. Optional in java is a bad idea for a great many reasons; lombok does not introduce features that make it too easy to write bad code. For java, optional for getters is bad code. We will not introduce this optional=true concept as a consequence.Bacardi
Dealing more and more with functional programming it makes it more and more valid to support Optional for Getters as the fromer comments suggest. I think this kind of religious thinking is going to hurt Lombok.Trainload
Traversal using flatmaps would be much easier with the Optional option. Optional.ofNullable(person).flatmap(p -> Optional.ofNullable(p.getAddress())).flatMap(a -> Optional.ofNullable(a.getCity()).ifPresent(city -> doSomething(city)) is pretty bulky. Whereas Optional.ofNullable(person).flatMap(Person::getAddress).flatMap(Address:getCity).ifPresent(city -> doSomething(city) to me, is a lot cleaner. Optional is a monad, but if the POJO makes is too verbose to utilize, no one will go that route....then we're back to nulls.Gavrielle
It's a pity this isn't supported just because Lombok developers believe "Optional in java is a bad idea" - feel free to avoid it within Lombok code, but Lombok users should have the choice.Pintail
@Gavrielle it becomes even easier if person is never null to begin with, e.g. the service returning it returns an Optional itself.Distraction
@RoelSpilker "We can always add features, but we really try to focus on the most important features first. This is in our opinion not one of them" The GitHub issue asking for this is now the most-requested open issue (excluding a dup of SuperBuilder which should be closed) so, respectfully, the users of Lombok disagree with you.Peacemaker
would be nice to mark this "Optionals should never be passed on, but unboxed by the calling code as soon as possible." clearly as a personal opinion in the answerErgotism
LOL. Nullables in Java are horrible. They just prevent proper type checking.Locarno
I've also run into the issue of Lombok Getters not supporting Optional. As an alternative to providing this feature, Lombok Getters should be able to return a default value instead of null. Something like @Getter(default = "") for a String type, for instance.Xylotomy
Optional IS a replacement for null, its source is actually completely centered around null-checking. You use it to tell your caller "Hey, here's a potentially empty value, please handle it" in a declarative and type-safe way. It also reduces a ton of boilerplate (and eliminates NPEs, when used correctly). You certainly CAN abuse Optional however, but that's up to the developer. We use lombok to reduce boilerplate, not to make our practices better. P.S. Just because you use a few lambdas here and there to handle empty values, doesn't mean you suddenly switched to the functional paradigm.Expositor
I just can say LOL. Optional is a good mechanism to force you to handle the potential absence of a value and helps you to write better readable code. Imho that fanatic "Optional is evil" way of thinking is a statement of old school minded imperative programmersPolymorphous
Interesting post #26328457Yeanling
The link to embracing-void-6-refined-tricks-dealing-nulls-java is broken, does someone have it?Pharmacopoeia
On Devoxx, Victor Rentea explains why should we have getters that return an Optional instead of null: youtu.be/YnzisJh-ZNI?t=515Modernity
this answer did not age well. As some has pointed out, Optional is a replacement for null.Remainderman

© 2022 - 2024 — McMap. All rights reserved.