Search code examples
javaoption-type

How to make a field optional?


I have a class like so

class User {
  private String firstName;
  private String lastName;

  ...
}

I want the lastName property to be optional. How do I accomplish this in Java?

In some languages it's quite elegant and simple wherein we just append a question mark after the field name.


Solution

  • Overview

    There is no language concept for this in Java.

    In Java, all (non-primitive) types are nullable, hence can be seen optional. So you could just assign it null and call it a day.

    To overcome the problems related with that, make intention clearer and strive for fail-fast, what I have seen being used a lot would be to assign null to it internally and return Optional<String> on methods that would return it, such as a getLastName() method.


    Code example

    So one way doing this could be:

    class User {
      private String firstName;
      private String lastName;
    
      User(@NotNull String firstName) {
         this(firstName, null);
      }
    
      User(@NotNull String firstName, @Nullable String lastName) {
        this.firstName = firstName;
        this.lastName = lastName;
      }
    
      @NotNull Optional<String> getLastName() {
        return Optional.ofNullable(lastName);
      }
    
      void setLastName(@Nullable String lastName) {
        this.lastName = lastName;
      }
    
      ...
    }
    

    I used the @NotNull and @Nullable annotations intentionally to make it clearer for you where null could be allowed in such a design.

    Note that if you have more optional parameters, a builder-pattern might also become handy.

    Ultimately, also think about whether having optional values is a good design in the first place - maybe you can redesign the entire thing on a bigger picture to aovid the situation all together.


    Optional as field or argument

    Note that it is usually not recommended to store the field as Optional<String>, nor to take such arguments, for example a setLastName(Optional<String>).

    Optional was designed only to be used by methods wo want to indicate the lack of a return value.

    You can read more about that here: