[英]How to make JUnit assertThat() work with lower bounded wildcard?
最初,我有这段生产代码:
interface ActionSequence {
public List<Actions> getActions();
我测试了实现该接口的类,如下所示:
assertThat(sequenceUnderTest.getActions(), is(Arrays.asList(action1, action2));
然后我认为将生产界面更改为:
public List<? extends Action> getActions() {
(允许我返回Action的子类列表)。
但是现在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的类时
@Override
public List<SomeSubClassOfAction> getActions()
(而不是保持通配符)...然后一切正常。 但为什么?
Arrays.asList(action1, action2)
将返回List<Action>
。 is(Arrays.asList(action1, action2))
将返回Matcher<List<Action>>
。
assert具有以下签名:
assertThat(T actual, Matcher<T> matcher)
所以assertThat在你的情况下需要以下参数:
assertThat(List<Action>, Matcher<List<Action>>)
但是你的第一个参数是List<? extends Action>
List<? extends Action>
List<Action>
与List<? extends Action>
完全不同List<? extends 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()
答案是协变回报 。 由于允许Java1.5子类专门继承返回的继承方法。
但我不建议在返回参数中使用通配符类型,因为它不是客户端友好的。 请参阅通用通配符类型不应用于返回参数及其来自Effective Java的引用
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.