Java 8 Optional cannot be applied to interface

  • A+

Using Optional, I want to return a certain implementation (First or Second) of an interface according to the mapping result. This is the interface that First and Second implement:

public interface MyInterface {     Number number(); } 

The following Optional usage is erroneous:

final String string = ...                          // might be null final Number number = Optional.ofNullable(string)         .map(string -> new First())         .orElse(new Second())                      // erroneous line         .number(); 

orElse (com.mycompany.First) in Optional cannot be applied to (com.mycompany.Second)

Why is the line erroneous since both of the classes First and Second implement the interface MyInterface and the method MyInterface::number returns Number? How to implement this correctly?


The problem is that Java infers the mapped type to be First, and Second is not an instance of First. You need to explicitly give Java a bit of a nudge to know the right type:

private static void main(String... args) {     final String string = "";     final Number number = Optional.ofNullable(string)         .<MyInterface>map(str -> new First())  // Explicit type specified          .orElse(new Second())         .number(); } 

This is a generic limitation of type inference along method chains. It's not limited to Optional.

There has been some suggestion to have type inference work along method chains. See this question: Generic type inference not working with method chaining?

Maybe in a future version of Java the compiler will be clever enough to figure this out. Who knows.


:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: