Reputation: 140427
initially, I had this piece of production code:
interface ActionSequence {
public List<Actions> getActions();
I tested classes implementing that interface with something like this:
assertThat(sequenceUnderTest.getActions(), is(Arrays.asList(action1, action2));
Then I figured that it might be beneficial to change the production interface to:
public List<? extends Action> getActions() {
(to allow me to return lists of subclasses of Action).
But now eclipse tells me:
The method assertThat(T, Matcher<? super T>) in the type Assert is not applicable for the arguments (List<capture#1-of ? extends Action>, Matcher<List<Action>>)
I figured: when I change the class that implements ActionInterface to do
@Override
public List<SomeSubClassOfAction> getActions()
(instead of keeping the wildcard) ... then everything works. But why?
Upvotes: 1
Views: 513
Reputation: 3175
Your question was, why
@Override
public List<SomeSubClassOfAction> getActions()
is a legal Implementation of
public List<? extends Action> getActions()
The Answer is covariant return. Since Java1.5 subclasses are allowed to specialize the return of inherited methods.
But I wouldn't recommend having wildcard types in return parameters because it isn't client friendly. See Generic wildcard types should not be used in return parameters and its quote from Effective Java
Upvotes: 1
Reputation: 2012
Arrays.asList(action1, action2)
will return a List<Action>
.
is(Arrays.asList(action1, action2))
will therefore return a Matcher<List<Action>>
.
assertThat has the following signature:
assertThat(T actual, Matcher<T> matcher)
So assertThat requires the following parameters in your case:
assertThat(List<Action>, Matcher<List<Action>>)
But your first parameter is a List<? extends Action>
And a List<Action>
is completely different from a List<? extends Action>
.
For example, you cannot put Action elements into a List<SomeSubClassOfAction>
.
This is why this won't work.
For details, see Angelika Langer's excellent site: http://www.angelikalanger.com/GenericsFAQ/FAQSections/Index.html
Upvotes: 2