Optional Type returns a null value

29,935

Solution 1

An Optional always contains a non-null value or is empty, yes, but you don't have an Optional, you have a reference of type Optional pointing to null. You need to initialize testString, e.g. to Optional.empty().

Optional isn't magic, it's an object like any other, and the Optional reference itself can be null. It's the contents of the Optional that can't be null.

Solution 2

From the oracle documentation for the Optional type :

A container object which may or may not contain a non-null value.

So, yes it will return null if the variable is set to null. More info here

Solution 3

I always like to store the internal fields of the class as their actual values, and use return Optional.ofNullable(theField) in the getter method. This ensures that the method will always return some type of optional. In other words, you never run into the situation where your method which is supposed to return an optional is returning null.

So in your case:

private String testString;

...

public Optional<String> getTestString() {
      return Optional.ofNullable(testString);
}

In additional to the 'never returning null' benefit, this approach should also be more behaved when using things like Gson to marshal instances of your class into a format like JSON. I haven't tried Gson with Java 8 optionals, but with Guava optionals they don't serialize very nicely into JSON without a type adapter. If you're storing the raw value and then wrapping them with Optionals at your getter methods, they serialize into JSON in just the manner you would expect.

Share:
29,935
Gadam
Author by

Gadam

Updated on July 17, 2022

Comments

  • Gadam
    Gadam almost 2 years

    I have a class like this.

    public class SomeClass {
    
      private Optional<String> testString;
    
      public SomeClass() { 
          populateFields();
      }
    
      public Optional<String> getTestString() {
          return testString;
      }
    
      private void populateFields() {
         if(//something is going false here){
           testString = functionThatReturnsOptionalString();
         }
      }
    
    }
    

    Now instanceOfSomeClass.getTestString() returns null. Isn't Optional always supposed to contain a non-null value or be empty? I am trying or avoid isNull() and just use isEmpty() in my caller.

    If I put a breakpoint on the first line of populateFields() and check the value in testString at that time, it shows the value as null. Meaning the default value for this field(before being assigned anything) is null.

    Please shed light on this situation; and maybe the correct usage of Optional?

  • Louis Wasserman
    Louis Wasserman about 9 years
    Optional does not expose a constructor; you can't do new Optional.
  • Gadam
    Gadam about 9 years
    That would mean I should convert the Optional<String> returned by functionThatReturnsOptionalString() into a String first. So its like Optional to String to Optional again. Is that a good idea?
  • Gadam
    Gadam about 9 years
    Your answer makes sense to me, though I still miss complete clarity. "Optional isn't magic, it's an object like any other, and the Optional reference itself can be null. It's the contents of the Optional that can't be null." Can you give a code example? Or point me to a resource. I mean, so what exactly is the magic of Optional? Sorry if this sounds basic.
  • Dogs
    Dogs about 9 years
    Well, that all depends on the usage profile. There is an added object creation step involved with my approach. In 99.99% of uses for a method like this, this won't matter, but if you're calling this method 1000 times per second in an extremely performance sensitive situation, this approach might be too expensive. If you do have a performance sensitive situation, define a minimum performance threshold, and measure both approaches to see if there is a performance reason not to. But in all likelihood, you shouldn't be prohibited by performance
  • Louis Wasserman
    Louis Wasserman about 9 years
    It isn't magic. It's just a normal class that can hold either a nonnull value or be empty. Not sure what you want an example of.
  • Gadam
    Gadam about 9 years
    "It's the contents of the Optional that can't be null" -- how is that enforced? What would be an illegal line of code/compiler error?
  • Louis Wasserman
    Louis Wasserman about 9 years
    It's not done in the compiler; it just throws an exception in Optional.of if you pass a null argument.
  • Gadam
    Gadam about 9 years
    Thanks Dogs. This is a big data environment, where this code is part of a batch program that runs and processs approx 6 million records everyday (for now). In this context, I should be leaning towards just initializing the testString with Optional.empty(); ?
  • Dogs
    Dogs about 9 years
    Is the method being called for all of those records? Did you tests it to see if it was too slow?
  • Gadam
    Gadam about 9 years
    Yes an instance of SomeClass is created for each record. I do see your point about not being too much of a performance issue, unfortunately I have to check in the code now without performance testing. But this is a great way of using Optional which I will be using in all my code going forward. Thanks much.
  • Gadam
    Gadam about 9 years
    Doug's answer helped me much. But this answer is more relevant to the original question. So marking it as the answer. Thanks.
  • Stephan Herrmann
    Stephan Herrmann about 9 years
    Optional is good for avoiding the use of null, it has nothing to do with statically detecting null problems. If you are interested in compiler support for detecting null problems, consider using null annotations.