Optional in Java 8
Optional Class
Optional is a container class introduced in Java 8, designed to handle situations where a value may or may not be present. Instead of returning null, which can lead to NullPointerException when dereferenced, methods can return an Optional object. This approach forces developers to explicitly deal with the possibility of an absent value, thereby reducing the chances of runtime exceptions due to null references.
Before Java Optional, developers had to manually check if a value was null to handle NullPointerExceptions in Java applications. Imagine you have a method called getText() that returns a string, and you want to print its uppercase version to the console in the main method.
private static String getText() {
String text = "Hello World";
return text;
}public static void main(String[] args) {
System.out.println(getText().toUpperCase());
}This works totally fine until, for some reason, the getText() function returns a null value. If you haven’t prepared for null values and you try to perform .toUpperCase() to a null value, you’ll get a NullPointerException in your program.
private static String getText() {
String text = null;
return text;
}
So the simplest solution to avoid a NullPointerException is to check if the value is null before performing any operations on it.
public static void main(String[] args) {
if(getText()!=null)
System.out.println(getText().toUpperCase());
else
System.out.println("Value is Null");
}Optional class methods
- Optional.of() : Creates an
Optionalwith a non-null value. ThrowsNullPointerExceptionif the argument is null. - Optional.ofNullable() : Creates an
Optionalthat may or may not hold a non-null value. Doesn't throw an exception if the argument is null. - get() : Returns the value if present; otherwise, throws
NoSuchElementException. - Optional.empty() : Represents an empty
Optionalinstance, meaning no value is present. - isPresent() : Returns
trueif there is a value present, otherwisefalse. - ifPresent() : Performs the given action if a value is present.
- orElse() : Returns the value if present; otherwise, returns the specified default value.
- orElseGet() : Returns the value if present; otherwise, returns the result produced by the given supplier.
- orElseThrow() : Returns the value if present; otherwise, throws an exception created by the provided supplier.
Example : Optional class methods are implemented in this example.
Here’s the Employee class:
public class Employee {
private String name;
private int id;
// Constructor
public Employee(String name, int id) {
this.name = name;
this.id = id;
}
// Getters
public String getName() {
return name;
}
public int getId() {
return id;
}
@Override
public String toString() {
return "Employee{name='" + name + "', id=" + id + "}";
}
}Now, let’s use various Optional methods with this Employee class:
import java.util.Optional;
public class OptionalExample {
public static void main(String[] args) {
// Create an Employee instance
Employee emp1 = new Employee("John Doe", 123);
Employee emp2 = null;
// Optional.of() - Creates an Optional containing the given non-null value
Optional<Employee> optionalEmp1 = Optional.of(emp1);
System.out.println("Optional.of(emp1): " + optionalEmp1);
// Output: Optional[Employee{name='John Doe', id=123}]
// Optional.ofNullable() - Creates an Optional containing the given value or empty if null
Optional<Employee> optionalEmp2 = Optional.ofNullable(emp2);
System.out.println("Optional.ofNullable(emp2): " + optionalEmp2);
// Output: Optional.empty
// get() - Returns the value if present, otherwise throws NoSuchElementException
System.out.println("optionalEmp1.get(): " + optionalEmp1.get());
// Output: Employee{name='John Doe', id=123}
// Optional.empty() - Creates an empty Optional
Optional<Employee> emptyOptional = Optional.empty();
System.out.println("Optional.empty(): " + emptyOptional);
// Output: Optional.empty
// isPresent() - Checks if a value is present
System.out.println("optionalEmp1.isPresent(): " + optionalEmp1.isPresent());
// Output: true
System.out.println("emptyOptional.isPresent(): " + emptyOptional.isPresent());
// Output: false
// ifPresent() - Executes the given action if a value is present
optionalEmp1.ifPresent(emp -> System.out.println("Employee found: " + emp));
// Output: Employee found: Employee{name='John Doe', id=123}
optionalEmp2.ifPresent(emp -> System.out.println("This will not be printed"));
// Output: (No output, since optionalEmp2 is empty)
// orElse() - Returns the value if present, otherwise returns a default value
Employee defaultEmp = new Employee("Default Employee", 0);
System.out.println("optionalEmp2.orElse(defaultEmp): " + optionalEmp2.orElse(defaultEmp));
// Output: Employee{name='Default Employee', id=0}
// orElseGet() - Returns the value if present, otherwise calls a supplier function to get a default value
System.out.println("optionalEmp2.orElseGet(() -> new Employee('Supplier Employee', 1)): " + optionalEmp2.orElseGet(() -> new Employee("Supplier Employee", 1)));
// Output: Employee{name='Supplier Employee', id=1}
// orElseThrow() - Returns the value if present, otherwise throws a custom exception
try {
System.out.println("optionalEmp2.orElseThrow(() -> new RuntimeException('No Employee found')): " + optionalEmp2.orElseThrow(() -> new RuntimeException("No Employee found")));
} catch (RuntimeException e) {
System.out.println(e.getMessage());
}
// Output: No Employee found (as an exception message)
}
}👏 If you found my articles useful, please consider giving it claps and sharing it with your friends and colleagues.
- Mastering Transaction Propagation and Isolation in Spring Boot
- SOLID Principles in Java
- Java String Interview Questions and answer
- Design Pattern in java
- Kafka Interview Questions and Answers
- Java 8 Interview Questions and Answer
- Global exception handling in spring boot
- Pessimistic Locking in JPA with Spring Boot
- Optimistic Locking in JPA with Spring Boot
- Generic ApiResponse and Global Exception Handling in Spring Boot
- One To One mapping in Spring Boot JPA
- One To Many mapping in Spring Boot JPA






