The most common and frequent exception which many Java developers encounter is NullPointerException. Though this is very common exception and the fix is also straightforward for most of the developers. They simply put null check or nested null checks in order to avoid happening this exception. This actually increases the number of indentation level in your code and also reduces the readability too. Even if you avoid happening this exception in this way, the complete flow might not be consistence with all client codes. If you fix this exception with simple null check, you need to make sure that the complete flow executes correctly as per business requirement without producing strange results from the application.
And also, there are many situations where, you add this null check only after happening the NullPointerException at least a once only. Yes, some developers proactively check the presence and absence of a value of variable before it is accessed and write the complete flow which handles the absence of the value.
Java 8 introduces java.util.Optional<T> to represent the absence of a value in a particular variable or a field of any type in more precise and safer manner. This enforces developers to specifically focus on the absence of the value of their reference, a variable or return type of a method. So defining a method to accept an optional or a method to return an optional indicates that the value of that variable may not be presence. There is a possibility of absence of the value. Your peer developers or in future, if someone is going to modify the code or use those methods by different client code, they will know that the value of the reference can be absence and should write the client code according to that.
public Employee findEmployeeByName(String name) {
Employee emp = null; // code get employee from DB or somewhere.
return emp;
}
public Optional<Employee> findEmployeeOptionalByName(String name) {
Employee emp = null; // code to get employee from DB or somewhere
return Optional.ofNullable(emp);
}
//Client code1
Employee emp = employeeRepository.findEmployeeByName("David");
System.out.print(emp.getName());
//Client code2
Optional<Employee> employeeOptional = employeeRepository.findEmployeeOptionalByName("David");
System.out.println(employeeOptional.get().getName());
//unwrap optional with isPresent() method
if(employeeOptional.isPresent()) {
System.out.println(employeeOptional.get().getName());
}
//unwrap optional with orElse() method
String empName = employeeOptional.map(Employee::getName).orElse("Unknown");
System.out.print(empName);
String empName = employeeOptional.map(Employee::getName).orElseGet(() -> "Unknnow");
System.out.println(empName);
String empName = employeeOptional.map(Employee::getName).orElseThrow(() -> new RuntimeException("Unable to find employee"));
System.out.print(empName);
You can apply map(), flatMap() and filter() methods to an optional similar as stream API.
0 comments:
Post a Comment