Working with Optionals

This tutorials assumes you are familiar with lambda expressions. Take a look at the Lambda Introduction first, if you are not!

The Optional class is widely used in Javacord. Basically, every method which might return a null value will return an Optional in Javacord instead. Optionals will help you to avoid NullPointerExceptions and make very clear if a method may not have a result. Here’s a small example:

The old way of doing it

User user = api.getCachedUserById(123L);
if (user != null) {

The new way of doing it

api.getCachedUserById(123L).ifPresent(user -> user.sendMessage("Hi!"));


The Optional class has a ton of useful methods which can all be found in the JavaDocs. Here’s a small explanation of the most important ones:


This method just returns the value of the Optional. You should only use this method if you are sure that the Optional contains a value, because it throws a NoSuchElementException if it does not contain a value.


TextChannel channel = api.getTextChannelById(123L).get();


This method checks if the Optional contains a value.


Optional<TextChannel> channel api.getTextChannelById(123L);
if (channel.isPresent()) {
  // A text channel with the id 123 exists. It's safe to call #get() now


This method returns the value of the Optional or the given “default” value if the Optional does not contain a value.


String name = user.getNickname(server).orElse(user.getName());

Hint: In this case you could also just use user.getDisplayName(server)


This is definitely one of the more interesting methods. It takes a Consumer as it’s argument which is called if the Optional contains a value. Together with lambda expressions this can be a very handy method.


api.getTextChannelById(123L).ifPresent(channel -> channel.sendMessage("Hi!"));


This methods “converts” the type of an Optional. This might be useful, if the Optional does not contain the final value you need.


String currentGame = api.getYourself().getActivity().map(Activity::getName).orElse("None");


This method filters the value of an Optional for additional criteria. E.g. if you only want a bot user by id.


Optional<User> botUser = api.getCachedUserById(123).filter(User::isBot);


Just try to understand the following code. If you do, you won’t have much trouble with Optionals. It won’t get any harder. 🙂

String currentGame = api.getCachedUserById(123)

Hint: Both getCachedUserById(...) and getActivity(...) return an Optional

String currentGame = api.getUserById(123) // Gets an Optional<User>
        .map(User::getActivity) // "Converts"/Maps the user to a Optional<Activity>. The value is now Optional<Optional<Activity>>
        .filter(Optional::isPresent) // Checks if the activity (game) exists
        .map(Optional::get) // "Converts"/Maps the Optional<Optional<Game>> to Optional<Game>
        .map(Activity::getName) // "Converts"/Maps the activity object to the name of the activity (a String)
        .orElse("None"); // If the user does not exist or doesn't play a game, currentGame is "None"

Improve this page