26

I have a question regarding Java 8's Optional, the purpose of which is to tackle NullPointerException exceptions.

The question is, what is the reason for having both types to let us choose:

Optional.of(T value)     <-----non-null value, null value will throw NPE
Optional.ofNullable(T value)   <----- nullable value

Because what I expect is, when I use:

Optional.of(nullValue);

It won't throw a NullPointerException.


Expanded my question after some replies:

Why would people opt for Optional instead of normal if-else for null checking?

Boann
  • 48,794
  • 16
  • 117
  • 146
hades
  • 4,294
  • 9
  • 46
  • 71
  • 1
    You may want to return a value wrapped with Optional. In this case, you can use `Optional.of(value);` . – Emre Savcı Dec 17 '18 at 06:51
  • 3
    Two out of three answers provided by people call NullPointer. How apt for this question.... – Thilo Dec 17 '18 at 07:07
  • 1
    Because they didn't think it through, that most normal expectation is that `of(value)` should check for null. This design choice is as absurd as the `java.util.Date` type. – coladict Dec 17 '18 at 07:13
  • 8
    Because, as others have said in answers, `Optional` is designed to reduce NPEs at the _method caller_ level, not necessarily at the _method implementation_ level. `Optional.of` is for when one _knows_ the value _is not_ `null` (and an error should be thrown if it is), `Optional.empty` is for when one _knows_ the value _is_ `null`, and `Optional.ofNullable` is for when one is _not sure_ if the value is `null` or not. – Slaw Dec 17 '18 at 07:58
  • 2
    Biggest question for me is why the chose the naming that way. I would use `.of()` for nullable values and then make `ofNotNull()` for non null values, as this latter is way less used. – Robert Niestroj Dec 17 '18 at 07:59
  • 1
    @Slaw In what cases would it make sense for the result of `Optional.of` to be `Optional` at all? You know it's not `null`, it's enforced to not be. Edit: You mean a method that returns either `Optional.of` or another `Optional` that actually can be empty? – JollyJoker Dec 17 '18 at 08:50
  • 2
    @JollyJoker In cases where the logic of the (`Optional` returning) method deems the result has been found and is not, or should not be, `null`. One example would be "short-circuiting" a loop when a match is found by returning `Optional.of(matchedItem)`. If no match was found the loop would complete and the method would return `Optional.empty`. However, there are (perhaps more frequent, perhaps not) cases where even the method cannot know if the result is `null` or not and must use `Optional.ofNullable` when returning. – Slaw Dec 17 '18 at 09:10
  • 1
    @Slaw Wrote [an answer](https://stackoverflow.com/a/53811956/7126740) that hopefully captures what you mean. – JollyJoker Dec 17 '18 at 09:13
  • [Why use Optional.of over Optional.ofNullable?](https://stackoverflow.com/questions/31696485/why-use-optional-of-over-optional-ofnullable) and [Uses for Optional](https://stackoverflow.com/questions/23454952/uses-for-optional) might already contain the answers you are looking for... (or follow the linked questions/answers from there on) – Roland Dec 17 '18 at 11:26
  • For example the answer(s) of [Is there a real reason to use Optional.of()?](https://stackoverflow.com/questions/41181509/is-there-a-real-reason-to-use-optional-of) might also be helpful to you – Roland Dec 17 '18 at 11:33
  • regarding your "enhanced question" (shouldn't that rather be its own one?)... within a method you could probably rather stick to `if`/`else`, but as a caller of a method, you probably rather prefer `Optional`. In the end, what does `null` even mean? not initialized? error? is not present? You would need to define that as a contract... wherease `Optional` itself describes already what the returned value will be... either present or absent... – Roland Dec 17 '18 at 11:44

8 Answers8

28

The javadoc of Optional.of reads that explicitly :

@throws NullPointerException if value is null

and that is where the requirement of handling the cases as expected by you comes into picture with the use of Optional.ofNullable which is a small block of code as :

public static <T> Optional<T> ofNullable(T value) {
    return value == null ? empty() : of(value); // 'Optional.of'
}

That said, the decision of choosing one over the other would still reside with the application design as if your value could possibly be null or not.


On your expectation part, that was not what the Optional was actually intended for. The API note clarifies this further (formatting mine):

Optional is primarily intended for use as a method return type where there is a clear need to represent "no result," and where using null is likely to cause error. A variable whose type is Optional should never itself be null; it should always point to an Optional instance.


purpose of Optional is to tackle NullPointerException exception.

Aside: Just to call it out clearly, that the choice would of course implicitly let you define if an NPE should be thrown at runtime or not. It's not determined at the compile time though.

Naman
  • 27,789
  • 26
  • 218
  • 353
12

the purpose of Optional is to tackle NullPointerException exception

Yes, it is, but at usage time not at creation.

So when you receive an Optional from a method then you can avoid NPE by using Optional.ifPresent, Optional.orElse,Optional.orElseGet and Optional.orElseThrow methods.

But this is not the case when you're creating an Optional. Since it's your own method you have to know whether the object is nullable or not.


The main point of Optional is to provide a means for a function returning a value to indicate the absence of a return value. See this discussion. This allows the caller to continue a chain of fluent method calls.

Stuart Marks

Please read this post for more detailed explanation.

ETO
  • 6,970
  • 1
  • 20
  • 37
9

I think it's quite simple and clear with Javadoc:

Optional.of(T value) is used when you are sure that there is never a null value and incase null value occurs than program throws NullPointerException and consider as bug.

Optional.ofNullable(T value) is used when you know that there can be a null value and in case of it your program should behave normally.


Why would people opt for Optional instead of normal if-else method for null checking?

Pang
  • 9,564
  • 146
  • 81
  • 122
NullPointer
  • 7,094
  • 5
  • 27
  • 41
7

Why would people opt for Optional instead of normal if-else method for null checking?

The main point of Optional<T> class is to provide a mean for performing null safe mapping operations.

employeeOptional.map(Employee::getName).map(String::toUpperCase).ifPresent(upperCasedNameConsumer)

The expression above can replace a cascade of if-else statements in a single readable expression.

Optional.of provides an assertion for the given argument to be a null-null value, otherwise, you can opt for Optional.ofNullable if you are not sure about the input.

I strongly recommend you to read the javadoc for Optional<T> class for more optional chaining methods that you can use for your advantage.

HPH
  • 388
  • 2
  • 11
6

After reading some answers and comments I think this explanation is missing. Consider a method like

public Optional<String> name(Customer c) {
    return c.isNew() ? Optional.ofNullable(getName(c)) : Optional.of(getName(c));
}

Here you want to throw a NullPointerException if the customer isn't new and is supposed to have a name; your code is inconsistent if that's ever null. Yet the name may not yet exist if the customer is new, hence ofNullable in that case and the method returns Optional.

JollyJoker
  • 1,256
  • 8
  • 12
3
  • Optional.ofNullable is a wrapper around existing APIs that can return null. You would call it as a consumer of an API.
  • Optional.of/Optional.empty is for new code written with Optional in mind. You would return an Optional created with of/empty as a provider of an API.
dnt
  • 113
  • 1
  • 5
1

Code example: Optional.of() VS Optional.ofNullable()

@Test
public void TestOptional() {

    String message = "Hello World!";
    System.out.println("message -> " + message + "\n");

    Optional<String> genderOptional = Optional.of(message);
    System.out.println("Optional.of(message) -> " + genderOptional);
    System.out.println("Optional.of(message).get() -> " + genderOptional.get());
    try {
        Optional.of(null);
    } catch (java.lang.NullPointerException e) {
        System.out.println("Optional.of(null) -> java.lang.NullPointerException \n");
    }

    System.out.println("Optional.empty() -> " + Optional.empty() + "\n");

    System.out.println("Optional.ofNullable(null) -> " + Optional.ofNullable(null));
    System.out.println("Optional.ofNullable(message) -> " + Optional.ofNullable(message));
    System.out.println("Optional.ofNullable(message).get() -> " + Optional.ofNullable(message).get());

}

Output:

message -> Hello World!

Optional.of(message) -> Optional[Hello World!]
Optional.of(message).get() -> Hello World!
Optional.of(null) -> java.lang.NullPointerException 

Optional.empty() -> Optional.empty

Optional.ofNullable(null) -> Optional.empty
Optional.ofNullable(message) -> Optional[Hello World!]
Optional.ofNullable(message).get() -> Hello World!
Eddy
  • 3,623
  • 37
  • 44
0

I think the main purpose is that using Optional.of() can throw null-pointer which is exactly what we need in some cases.

palaѕн
  • 72,112
  • 17
  • 116
  • 136
Kesa_Wu
  • 47
  • 7