Search code examples
javaoption-typenarrowing

Optional<> and return type narrowing


In Java < 8, returning "unsafe" objects (objects or null), I was able to specialize return type in subclass:

class A {}
class B extends A {}
interface Sup { A a(); /* returns A instance, or null */ }
interface Sub extends Sup { B a(); }

In Java 8, if I want to make my API "safer", I should return Optional<A> instead of "raw" A:

interface Sup { Optional<A> a(); }
interface Sub extends Sup { Optional<B> a(); }

But doesn't compile! Because Optional<B> is not a subclass of Optional<A>.

How I'm supposed to resolve this issue?


Solution

  • You could use wildcards.

    interface Sup { Optional<? extends A> a(); }
    
    interface Sub extends Sup { Optional<? extends B> a(); }
    

    I could have made it just Optional<B> but using Optional<? extends B> allows another interface to extend Sub and do the same thing.

    Personally, I think this is a bit of a mess, and it would be preferable to just return A or B, or null where necessary.