Quiz yourself: Use the Optional class (advanced)

Do you know how to use Optional? Find out in the latest by Simon and Mikalai.

August 11, 2020 | Download a PDF of this article
More quiz questions available here

If you have worked on our quiz questions in the past, you know none of them is easy. They model the difficult questions from certification examinations. The “intermediate” and “advanced” designations refer to the exams rather than to the questions, although in almost all cases, “advanced” questions will be harder. We write questions for the certification exams, and we intend that the same rules apply: Take words at their face value and trust that the questions are not intended to deceive you but to straightforwardly test your knowledge of the ins and outs of the language.

The goal of this quiz is to test your knowledge of the Java Optional class.

Given the class:


import java.util.Optional;
public class OptionalArgs {
	public static void main(String[] args) {
		var v = Optional.ofNullable(args[0])
				     .or(() -> Optional.ofNullable(args[1]))
				     .flatMap(o -> Optional.empty())
				     .stream().findFirst().orElse("default");
		System.out.print(v);
	}
}

What is the output if you run the compiled class as shown below? Choose one.


java OptionalArgs Java

A. A runtime exception
B. Blank output
C. Java
D. default
 

Answer. Let’s work through the steps of execution this Java SE 11 code will perform to determine the result. First, invoke the program with a single command-line argument: Java. This enters the program through the args array that is the argument of the main method. So, args[0] contains the string "Java"—and, significantly, it is not null. Next, the factory method ofNullable is called with args[0] as its argument. This constructs an Optional that contains the string "Java".

Next, the code invokes the or method on the newly created Optional. The argument to this method is a Supplier<Optional<String>>, which is invoked if the Optional is empty. In this way, the or method can serve to provide a fallback value. However, in this case, the Optional is not empty, so no fallback value is needed and the Supplier is not invoked.

Because the Supplier is not called, the code that would attempt to access args[1] is not executed, and the ArrayIndexOutOfBoundsException that would have been thrown is avoided—because only one argument is provided to the program. So far at least, the code is still running normally, and you’re dealing with an Optional containing "Java".

There are two things to note. First, the or method did not appear until Java 9. Second, the reason the argument to or in this case is Supplier<Optional<String>> is because the code indicated that the original Optional would contain a String; if that String is missing, it’s the responsibility of this Supplier to generate an alternate value wrapped in an Optional. If the Supplier produced a value containing something other than String, it would not be a suitable alternative.

At this point, you have a nonempty Optional and the code calls flatMap on it. Because the Optional is not empty, the value inside the Optional is passed to the function provided as the argument to the flatMap call. That function must return some kind of Optional, which is normal for flatMap operations, and the content type is permitted to change. In a regular situation, that function would most probably do some processing on the value that is passed to it. In this case, however, the function ignores its argument entirely and simply returns an empty Optional.

Next, the code creates a stream from the empty Optional. (Making a stream of either zero elements or one element directly from an Optional is another feature that was added in Java 9.) Because the stream() method is called on an empty Optional, the resulting stream will also be empty and the call to the method findFirst() that follows it returns another empty Optional. In effect, the stream() and findFirst() calls take you from an Optional back to another Optional with the same contents. In this case, the contents are empty.

Finally, the orElse method is called. This method returns the value contained in the Optional or, if the Optional is empty, the value that’s the argument of orElse. Because the Optional is empty, the final result will be the argument to orElse, which is "default". Therefore, default is printed to the console.

The correct answer is option D.

[Find more about Optional in two articles by Mohamed Taman: 12 recipes for using the Optional class as it’s meant to be used and The Java Optional class: 11 more recipes for preventing null pointer exceptions. —Ed.]

Simon Roberts

Simon Roberts joined Sun Microsystems in time to teach Sun’s first Java classes in the UK. He created the Sun Certified Java Programmer and Sun Certified Java Developer exams. He wrote several Java certification guides and is currently a freelance educator who publishes recorded and live video training through Pearson InformIT (available direct and through the O’Reilly Safari Books Online service). He remains involved with Oracle’s Java certification projects.

Mikalai Zaikin

Mikalai Zaikin is a lead Java developer at IBA IT Park in Minsk, Belarus. During his career, he has helped Oracle with development of Java certification exams, and he has been a technical reviewer of several Java certification books, including three editions of the famous Sun Certified Programmer for Java study guides by Kathy Sierra and Bert Bates.

Share this Page