我正在使用Java 8,以下是我的测试代码,使用JUnit和AssertJ:
@Test
public void test() {
List<Number> actual = new ArrayList<>();
actual.add(Double.valueOf(1));
actual.add(Integer.valueOf(1));
actual.add(Long.valueOf(1));
List<Class<? extends Number>> expected = new ArrayList<>();
expected.add(Double.class);
expected.add(Integer.class);
expected.add(Long.class);
// Just information how IDEA is generating types for the different statements
ListAssert<? extends Class<? extends Number>> implicitLambda = assertThat(actual).extracting(t -> t.getClass());
ListAssert<Class<? extends Number>> explicitLambda = assertThat(actual).extracting((Extractor<Number, Class<? extends Number>>) t -> t.getClass());
ListAssert<Class<?>> methodReference = assertThat(actual).extracting(Number::getClass);
// Does not compile
// Error:(31, 84) java: incompatible types: java.util.List<java.lang.Class<? extends java.lang.Number>> cannot be converted to java.lang.Iterable<? extends java.lang.Class<capture#1 of ? extends java.lang.Number>>
assertThat(actual).extracting(t -> t.getClass()).containsExactlyElementsOf(expected);
// Compile because of explicit types
assertThat(actual).extracting((Extractor<Number, Class<? extends Number>>) t -> t.getClass()).containsExactlyElementsOf(expected);
// Compile, but don't understand why
assertThat(actual).extracting(Number::getClass).containsExactlyElementsOf(expected);
}
在第一个assert中,我得到了一个编译错误:
Error:(31, 84) java: incompatible types: java.util.List<java.lang.Class<? extends java.lang.Number>> cannot be converted to java.lang.Iterable<? extends java.lang.Class<capture#1 of ? extends java.lang.Number>>
我的问题如下:
- 第一个assert中的lambda表达式的返回类型真的是
<? extends Class<? extends Number>
吗?
我只是依赖于IDEA生成的局部变量。 - 如果是这样,那么为什么呢?getClass文档说:
The actual result type is Class<? extends |X|> where |X| is the erasure of the static type of the expression on which getClass is called.
如果我理解正确,它应该是Class<? extends Number>
。 - 我应该使用哪个工具来查看隐式lambda的类型?我能用JDK中的某个工具来检查它吗?
- 为什么最后一个使用方法引用的assert可以编译通过?如果它真的返回
Class<?>
,那么我理解了,但为什么返回类型对于这个和隐式lambda不同呢?
相关的AssertJ文档:
AbstractIterableAssert
AbstractIterableAssert.html#extracting
AbstractIterableAssert.html#containsExactlyElementsOf