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?
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.
Change your parent bounds to use wildcards:
Optional<? extends A> // parent
Optional<? extends B> // child
The reason that your code doesn't work now is due to the fact that generics are invariant. B
is-an A
, but Optional<B>
is not an Optional<A>
.
来源:https://stackoverflow.com/questions/29869548/optional-and-return-type-narrowing