如何使 JUnit assertThat() 使用下限通配符?
How to make JUnit assertThat() work with lower bounded wildcard?
最初,我有这段生产代码:
interface ActionSequence {
public List<Actions> getActions();
我测试了 classes 实现该接口的方式如下:
assertThat(sequenceUnderTest.getActions(), is(Arrays.asList(action1, action2));
然后我认为将生产接口更改为:
可能会有所帮助
public List<? extends Action> getActions() {
(允许我 return 子 class 操作列表)。
但是现在eclipse告诉我:
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>>)
我想:当我将实现 ActionInterface 的 class 更改为
@Override
public List<SomeSubClassOfAction> getActions()
(而不是保留通配符)...然后一切正常。但是为什么?
Arrays.asList(action1, action2)
会 return 一个 List<Action>
。
is(Arrays.asList(action1, action2))
因此会 return 一个 Matcher<List<Action>>
.
assertThat 具有以下签名:
assertThat(T actual, Matcher<T> matcher)
因此 assertThat 在您的案例中需要以下参数:
assertThat(List<Action>, Matcher<List<Action>>)
但是你的第一个参数是List<? extends Action>
List<Action>
与 List<? extends Action>
完全不同。
例如,您不能将 Action 元素放入 List<SomeSubClassOfAction>
中。
这就是为什么这行不通的原因。
有关详细信息,请参阅 Angelika Langer 的优秀网站:http://www.angelikalanger.com/GenericsFAQ/FAQSections/Index.html
你的问题是,为什么
@Override
public List<SomeSubClassOfAction> getActions()
是
的合法实现
public List<? extends Action> getActions()
答案是协变return。由于 Java1.5 子类被允许专门化继承方法的 return。
但我不建议在 return 参数中使用通配符类型,因为它对客户端不友好。请参阅 Generic wildcard types should not be used in return parameters 及其引用自 Effective Java
最初,我有这段生产代码:
interface ActionSequence {
public List<Actions> getActions();
我测试了 classes 实现该接口的方式如下:
assertThat(sequenceUnderTest.getActions(), is(Arrays.asList(action1, action2));
然后我认为将生产接口更改为:
可能会有所帮助public List<? extends Action> getActions() {
(允许我 return 子 class 操作列表)。
但是现在eclipse告诉我:
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>>)
我想:当我将实现 ActionInterface 的 class 更改为
@Override
public List<SomeSubClassOfAction> getActions()
(而不是保留通配符)...然后一切正常。但是为什么?
Arrays.asList(action1, action2)
会 return 一个 List<Action>
。
is(Arrays.asList(action1, action2))
因此会 return 一个 Matcher<List<Action>>
.
assertThat 具有以下签名:
assertThat(T actual, Matcher<T> matcher)
因此 assertThat 在您的案例中需要以下参数:
assertThat(List<Action>, Matcher<List<Action>>)
但是你的第一个参数是List<? extends Action>
List<Action>
与 List<? extends Action>
完全不同。
例如,您不能将 Action 元素放入 List<SomeSubClassOfAction>
中。
这就是为什么这行不通的原因。
有关详细信息,请参阅 Angelika Langer 的优秀网站:http://www.angelikalanger.com/GenericsFAQ/FAQSections/Index.html
你的问题是,为什么
@Override
public List<SomeSubClassOfAction> getActions()
是
的合法实现public List<? extends Action> getActions()
答案是协变return。由于 Java1.5 子类被允许专门化继承方法的 return。
但我不建议在 return 参数中使用通配符类型,因为它对客户端不友好。请参阅 Generic wildcard types should not be used in return parameters 及其引用自 Effective Java