56

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?

Yassin Hajaj
  • 21,337
  • 9
  • 51
  • 89
Dhrumil Upadhyaya
  • 1,014
  • 2
  • 10
  • 14

1 Answers1

6

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.

E_net4
  • 27,810
  • 13
  • 101
  • 139
Roel Spilker
  • 32,258
  • 10
  • 68
  • 58
  • 38
    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 null[Guava's Optional](http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/base/Optional.html) 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 programmers – Dhrumil Upadhyaya Jul 28 '15 at 14:58
  • 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. – Roel Spilker Jul 29 '15 at 08:00
  • 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. – ymajoros Sep 01 '16 at 07:56
  • 2
    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? – Sir Celsius Jan 03 '17 at 17:01
  • 32
    I mean that the generated getters would look like the code sample [here](http://blog.codefx.org/java/stephen-colebourne-optional-a-strict-approach/) and would be added via something like `@Getter( optional = true )`. – Sir Celsius Jan 03 '17 at 17:06
  • 19
    Definitely a big YES for `@Getter( optional = true )` it would make me very happy. – Trynkiewicz Mariusz Apr 03 '17 at 19:56
  • 53
    "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. – Łukasz Biały Apr 15 '17 at 08:17
  • 1
    @Egregore just a quick note, it's called [vavr](http://www.vavr.io/) these days (; – Jezor Jan 26 '18 at 08:35
  • I'm well aware of that fact @Jezor :) – Łukasz Biały Jan 26 '18 at 21:17
  • @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. – krund Apr 07 '18 at 08:26
  • 13
    @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`? – Gerard Bosch Jan 22 '19 at 10:16
  • 3
    "Optionals should never be passed on, but unboxed by the calling code as soon as possible." - why? – dstibbe Feb 13 '19 at 19:34
  • 5
    "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'. – dstibbe Feb 13 '19 at 19:39
  • 2
    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! – Gerard Bosch Feb 14 '19 at 08:38
  • @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. – rzwitserloot Aug 12 '19 at 13:30
  • 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. – rzwitserloot Aug 12 '19 at 13:31
  • 9
    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. – Keyhan Nov 27 '19 at 11:51
  • 1
    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. – piper1970 Feb 15 '20 at 19:53
  • 4
    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. – Adrian Baker May 07 '20 at 01:59
  • 1
    @piper1970 it becomes even easier if `person` is never null to begin with, e.g. the service returning it returns an Optional itself. – ymajoros Jun 16 '20 at 07:36
  • 9
    @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. – Michael Aug 02 '20 at 22:01
  • 2
    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 answer – heldev Dec 20 '20 at 23:19
  • LOL. Nullables in Java are horrible. They just prevent proper type checking. – Arwed Mett Nov 03 '21 at 17:13
  • 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. – martin_wun Dec 22 '21 at 09:24
  • 4
    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. – Vanja D. Feb 16 '22 at 17:35
  • 3
    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 programmers – angeldelrio Mar 31 '22 at 15:16
  • Interesting post https://stackoverflow.com/questions/26327957/should-java-8-getters-return-optional-type – lascarayf Oct 13 '22 at 18:33
  • The link to embracing-void-6-refined-tricks-dealing-nulls-java is broken, does someone have it? – xedo Nov 14 '22 at 19:44
  • On Devoxx, Victor Rentea explains why should we have getters that return an Optional instead of null: https://youtu.be/YnzisJh-ZNI?t=515 – Paul Marcelin Bejan Mar 14 '23 at 10:49