87

In Java 8 you can return an Optional instead of a null. Java 8 documentation says that an Optional is "A container object which may or may not contain a non-null value. If a value is present, isPresent() will return true and get() will return the value."

In practice, why is this useful? Also, is there any case where using null would be preferred? What about performance?

Jadiel de Armas
  • 8,405
  • 7
  • 46
  • 62

3 Answers3

61

In practice, why is this useful?

For example let's say you have this stream of integers and you're doing a filtering:

int x = IntStream.of(1, -3, 5)
                 .filter(x -> x % 2 == 0)
                 .findFirst(); //hypothetical assuming that there's no Optional in the API

You don't know in advance that the filter operation will remove all the values in the Stream.

Assume that there would be no Optional in the API. In this case, what should findFirst return?

The only possible way would be to throw an exception such as NoSuchElementException, which is IMO rather annoying, as I don't think it should stop the execution of your program (or you'd have to catch the exception, not very convenient either) and the filtering criteria could be more complex than that.

With the use of Optional, it's up to the caller to check whether the Optional is empty or not (i.e if your computation resulted in a value or not).

With reference type, you could also return null (but null could be a possible value in the case you filter only null values; so we're back to the exception case).

Concerning non-stream usages, in addition to prevent NPE, I think it also helps to design a more explicit API saying that the value may be present or not. For example consider this class:

class Car {
   RadioCar radioCar; //may be null or not 
   public Optional<RadioCar> getRadioCar() {
        return Optional.ofNullable(radioCar);
   }
}

Here you are clearly saying to the caller that the radio in the car is optional, it might be or not there.

Alexis C.
  • 91,686
  • 21
  • 171
  • 177
  • 7
    Optional cannot contain null ... – ZhongYu Sep 08 '15 at 21:04
  • 38
    I still do not see why Optional is necassary here. For Object types we have null. For primitives, we have their Object-brothers, like Integer and Boolean, which can also be null to indicate "no value". So what is the benefit of optionals? – Alkis Mavridis Jun 28 '18 at 07:21
  • 37
    @AlkisMavridis I'm also confused why this answer is upvoted so heavily. None of the answers here present a compelling reason to use `Optional` over `null` other than the Java Stream API works well with it. As an aside, `Optional` can provide contractual hints to the developer, but so could proper documentation...At the end of the day, you are still checking if the value is null before operating on it. You've just changed the semantics from `if (value == null)` to `if (optionalValue.isPresent())`. And you've incurred the overhead of a couple method calls. – crush Aug 09 '18 at 17:33
  • 15
    The reason why Optionals are so useful is because with Optionals it forces you to represent your data in such a way that you can't invoke a method from `null`. Without Optionals it's not only possible, it's extremely easy to. In other words, you avoid sloppy logic and stupid errors. It has very little to do with convenience or verbosity. – eazar001 Aug 10 '18 at 00:05
  • 9
    Actually, after doing some research on Java and the Optional, my above statement is _not_ true. The typesystem in Java is not expressive nor strong enough to guarantee that like languages such as SML, F#, and Haskell do. It is still possible to incorrectly try to obtain a value when none is present even when using Optionals. That. Sucks. – eazar001 Aug 10 '18 at 02:11
  • 1
    Optional really shines when used in a **whole code base**. It means you are free to write code like `person.getName().length()`, no null check needed. Because if you do encounter null, that is a bug elsewhere (that needs fixing). – johv May 30 '20 at 21:21
  • 1
    @crush _As an aside, Optional can provide contractual hints to the developer, but so could proper documentation._ In my opinion this is the exact reason why it's useful and why Optionals should be encouraged over returning nulls. With documentations you're relying on someone keeping it up to date or even writing it in the first place. This, quite simply, is wishful thinking and doesn't happen. – Boris Nov 09 '21 at 00:51
29

When Java was first designed it was common practice to use a special value, usually called null to indicate special circumstances like I couldn't find what you were looking for. This practice was adopted by Java.

Since then it has been suggested that this practice should be considered an anti-pattern, especially for objects, because it means that you have to litter your code with null checks to achieve reliability and stability. It is also a pain when you want to put null into a collection for example.

The modern attitude is to use a special object that may or may not hold a value. This way you can safely create one and just not fill it with anything. Here you are seeing Java 8 encouraging this best-practice by providing an Optional object.

OldCurmudgeon
  • 64,482
  • 16
  • 119
  • 213
  • 127
    Can you elaborate on why a null check is clutter but a call to Optional.isPresent is not? – user100464 Oct 20 '16 at 15:58
  • 12
    I'd like to know also... – ycomp Dec 21 '16 at 16:34
  • 27
    If you only used Optional as a direct replacement for direct null checks with `Optional.isPresent` it would be of limited utility (still gives you explicit declaration at call sites that the value may be absent, which is good); the real power comes from being able to *defer* the error handling (no value) to a later time and chaining map/flatMap/filter etc. methods without if/else blocks. – DK_ Jan 08 '17 at 12:40
  • 6
    @user100464 The bug in the java language is that it allows null. Imagine a code base with `@NonNull` everywhere. Then Optional where null can happen. This gives much safer programs, and it is the direction Java will go as languages before it has (C++ refs for example). Optional removes the need for conditionals by using map and flatMap together with lambdas. Structuring code like this ensures no null checks go unnoticed. Just disallow calling isPresent and you HAVE to map to get to the data and you can't go wrong. – user239558 Feb 20 '17 at 15:11
  • 1
    @DK_ do you have an example? – shinzou Sep 26 '17 at 17:34
  • 8
    @shinzou If a method returns an optional, you can immediately call map/filter/flatMap and friends on it without worrying about it being empty; but all of these will only run if it has a value. When you want to handle the empty case, only then do you need to call getOrElse and friends to do so. – DK_ Sep 27 '17 at 19:28
  • 2
    @DK_ So, really, the reason is because `filter` and `map` were programmed by Oracle to take `Optional` into account, and not to do a `if (entry == null) {}`. Seems dumb to me, but to each his own I guess. I still don't see a compelling reason for these structures to exist. – crush Aug 09 '18 at 17:28
  • 2
    @crush `Optional` also makes it explicitly clear when an object can be null. For example, there are plenty of instances in most Java code where, by design, a `String` cannot be null. However, because the default `String` value *is* null, we must either keep track of where a `String` can/cannot be null, or else perform null checks before using a `String`. `Optional` eliminates this ambiguity by explicitly marking a value as "nullable". If we replace the concept of null with `Optional`, then anywhere a non-optional `String` shows up, we know it is guaranteed to have a value. – cariehl Sep 11 '18 at 19:43
  • @user100464 There are a lot more methods that you can use on `Optional`, and most of them are better than `isPresent`. For example, `map` and `flatMap`. So yes, why would you clutter your code with `isPresent`? That’s _your_ premise, not necessarily anyone else’s! – Guildenstern Jul 09 '20 at 14:16
  • @crush Apparently `filter` and `map` were programmed generically and aren’t littered with null checks. They don’t have to check whether the type is `Optional`, just like they don’t have to check that the type is a `Map`. What you’re advocating is that they should do _more_ checks (for nulls). I prefer the more generic approach. – Guildenstern Jul 09 '20 at 14:21
  • Optional would be great as a core feature in addition to not allowing objects to be null anymore. The pattern only works if there are only Optional and "GuaranteedNotNull" objects. As is we just gained a false sense of safety that non-optionals are not null, while the language does not guarantee it. – Danvil Nov 23 '21 at 07:34
1

Optional helps you to handle variables as available or not available and avoid check null references.

user3728064
  • 158
  • 1
  • 11
  • What does it mean for a variable to be available or not available? – Jadiel de Armas Feb 26 '15 at 15:41
  • 3
    Null reference is obviously not available, available otherwise, you'll use `Optional#isPresent` method to check safely for that – user3728064 Feb 26 '15 at 15:49
  • 8
    How are you avoiding a NULL check? You still have to do it, with .isPresent(), and then you have to do a method call to get the object. So this is more code And if you call .of it can still throw a NULL POINTER EXCEPTION so now you need a try/catch block or ANOTHER IF test for NULL. Optional requires more code not less. – BrianC Jan 23 '18 at 20:26
  • 4
    @BrianC From one of the above comments, `null` checking is something a programmer has to consciously do and Java does not catch this at compile time. `Optional` *helps* by making sure whoever is using an `Optional` knows that the value may not exist, and in some cases *forces* a programmer to do the equivalent of `null` checking for code to even compile. – Populus May 16 '18 at 17:38
  • 3
    @Populus So it's merely a construct used as a contract hint. Got it. – crush Aug 09 '18 at 17:29
  • 6
    You're still doing a null check, but now you're creating a second object to wrap your ultimate object, and having to do a virtual method call to invoke the null check. To me it seems that it is less efficient. – Evvo May 18 '20 at 20:59
  • sigh.. java re-introducing the same concept with a different name. no wonder kotlin is gaining so much popularity – frankelot Jul 31 '23 at 06:15