我有一个getter返回带有通配符的List:
import java.util.List;
public interface Foo {
List<? extends Bar> getList();
}
其中Bar
是其他界面。
当我用这样的AssertJ写一个断言时:
assertThat(foo.getList()).containsExactly(bar1, bar3);
编辑:我的完整用法是链接usingElementComparator
并提供Comparator<Bar>
来比较预期的Bar
个实例。
Comparator<Bar> comparator = createBarComparator()
assertThat(foo.getList()).usingElementComparator(comparator).containsExactly(bar1, bar3);
我收到此编译错误:
该方法包含ListAssert类型中的确切(捕获#46-of?extends Bar ...)不适用于参数(Bar,Bar)
我的第一个解决方案是投射结果:
assertThat((List<Bar>)foo.getList()).containsExactly(bar1, bar3);
然后我收到警告:
类型安全:从列表到列表的未选中投射
可以使用@SuppressWarnings("unchecked")
删除警告,但中间的强制转换不会使断言真正可读。
我的第二个解决方案是指示ELEMENT通用参数的值:
Assertions.<Bar>assertThat(foo.getList()).containsExactly(bar1, bar3);
好一点,但也不是那么好(没有静态导入可能,行的开头不方便可读性)
我想我正在寻找列表的其他assertThat
方法,其中类类型可以指定为第二个参数:
@CheckReturnValue
public static <ELEMENT> ListAssert<ELEMENT> assertThat(List<? extends ELEMENT> actual, Class<ELEMENT> c) {
return AssertionsForInterfaceTypes.assertThat(actual);
}
这样我就能写出这样的东西:
Assertions.assertThat(foo.getList(), Bar.class).containsExactly(bar1, bar3);
答案 0 :(得分:1)
以前用过Oracle JDK 7编译器,但这实际上是编译器中的一个错误,这已在Java 8 JDK中修复,因此编译错误是正常行为(无法找到错误参考虽然)。
我很乐意支持,但我不确定在AssertJ中是否可行,除非删除集合断言中的所有泛型用法。
assertThat(List, Class)
已经存在,但出于其他目的,所以没有运气。
可能的hack是定义你自己的assertThat
方法:
public static <T> ListAssert<Object> assertThat(final List<T> list) {
return Assertions.assertThat(list);
}
诀窍是返回ListAssert<Object>
。
虽然我理解编译错误的基本原理,但我不同意它的只读方法。